java設計模式精講 Debug 方式+記憶體分析 第6章 抽象工廠模式
抽象工廠模式
6-1 抽象工廠講解
工廠方法模式針對的就是產品等級結構
而抽象方法模式針對的就是產品族
我們只要在美的產品族裡面取空調,取出來的肯定是美的的空調,我們在美的的產品族裡面取冰箱,取出來的肯定也是美的的電冰箱,只要我們確定這個產品的產品族和產品等級結構,我們就可以唯一的確定這個產品:
從理論上來說:當一個工廠可以創建出分屬於不同產品等級結構的一個產品族中的所有物件時,那這個時候,抽象工廠模式要比工廠方法模式要更為簡單,更有效率;
6-2 抽象工廠coding
現在,我們提一個業務場景,現在提出了新的要求:每一個課程不僅僅要有視訊,還要有對應的手記,如果用工廠方法的方式來進行擴充套件的話 ,這個時候,既要有java的手記類,python的手記類,FE的手記類,還有手記的抽象類,手記的工廠,java的手記的工廠,python的手記的工廠,FE的手記的工廠,這個時候,就很容易出現類爆炸的現象;
原來是一個視訊是一個課程,現在一個視訊加上一個手記是一個課程;
java視訊,python視訊,fe視訊他們屬於同一產品等級,都是視訊
java手記,python手記,fe手記他們也屬於同一產品等級,都是手記
而java手記,java視訊他們處於同一產品族,都是java相關的;
同一產品族,我們就看java,還是python還是fe;
同一產品等級,我們就看它是視訊還是手記即可;
我們先來建立一個課程工廠:
課程類:
public abstract class Video {
public abstract void produce();
}
手記類:
public abstract class Article {
public abstract void produce();
}
課程工廠類:
public interface CourseFactory {
/** 獲取視訊 */
Video getVideo();
/** 獲取手記 */
Article getArticle();
}
現在來建立java產品族的課程工廠:
public class JavaCourseFactory implements CourseFactory {
@Override
public Video getVideo() {
return null;
}
@Override
public Article getArticle() {
return null;
}
}
Java視訊類:
public class JavaVideo extends Video {
@Override
public void produce() {
System.out.println("錄製Java視訊");
}
}
Java手記類:
public class JavaArticle extends Article {
@Override
public void produce() {
System.out.println("編寫Java課程手記");
}
}
現在,產品族裡面的工廠類就可以這樣來寫了:
public class JavaCourseFactory implements CourseFactory {
@Override
public Video getVideo() {
return new JavaVideo();
}
@Override
public Article getArticle() {
return new JavaArticle();
}
}
這裡就是把視訊工廠和手記工廠合在了一起;作為一個產品族;
我們再來寫一個python的產品族的:
PythonArticle類:
public class PythonArticle extends Article {
@Override
public void produce() {
System.out.println("編寫Python課程手記");
}
}
PythonVideo 類
public class PythonVideo extends Video {
@Override
public void produce() {
System.out.println("錄製Python的視訊");
}
}
現在,我們再來建立Python產品族的課程工廠(視訊和手記合在了一起):
public class PythonCourseFactory implements CourseFactory{
@Override
public Video getVideo() {
return new PythonVideo();
}
@Override
public Article getArticle() {
return new PythonArticle();
}
}
這個就是現在的類圖:
測試:
只要是從Java產品族裡面拿的肯定是Java的視訊和Java的手記
public class Test {
public static void main(String[]args){
CourseFactory courseFactory = new JavaCourseFactory();
Article article = courseFactory.getArticle();
Video video = courseFactory.getVideo();
/** 只要是從Java產品族裡面拿的肯定是Java的視訊和Java的手記 */
article.produce();
video.produce();
}
}
執行結果:
編寫Java課程手記
錄製Java視訊
這樣的話,就可以進行解藕;
在使用抽象工廠的時候,儘量找那種固定程度比較高的,像課程裡面的視訊和手記,視訊和手記都是必須要有的,就可以用抽象工廠模式來解決;
缺點:在新增產品等級的時候,會比較的麻煩;
如果在現有的產品族裡面新增新的產品等級,就違背了開閉原則了;
如果我們還要把原始碼放到課程的這個產品族裡面,那麼對原來的修改就比較大了;
6-3 抽象工廠原始碼解析
他們都是在同一個產品族裡面;