1. 程式人生 > 實用技巧 >工廠模式詳解

工廠模式詳解

簡述

  工廠模式是Java最常用的設計模式之一,這種模式屬於建立型模式,提供了一種建立物件的最佳模式。它並不是一個獨立的設計模式,而是三種功能接近的設計模式的統稱,分別是簡單工廠模式工廠方法模式抽象工廠模式

案例引入

  當我們例項化一個物件的時候,一般我們直接使用new關鍵字,但我們有沒有想到如果建立物件需要一系列複雜的初始化過程,我們就要在物件的建構函式寫很長很長的程式碼,大大降低了程式的可讀性,同時也可能導致程式的耦合度較高,這裡就可以提到我們的工廠模式了。

簡單工廠模式

  我們在例項化物件的時候,不使用new關鍵字,而是交由一個新的類,叫工廠類建立。

  我們來看一個例子,在我們的業務程式碼中,有個被廣泛引用的“口罩”類,這裡類例項需要在許多地方被建立和初始化,且初始化的程式碼較為複雜。

publicclassMask{
//建構函式
publicMask(){
//.....
//100行初始化程式碼
}
}

  此時我們就可以新建一個口罩工廠類,用於例項化口罩類,把初始化程式碼搬進工廠裡面。

publicclassMaskFactory{
 
publicMaskcreateMask(){
Maskmask=newMask();
//.....
//100行初始化程式碼
returnmask;
}
}

  如果口罩類存在子類,可以是繼承,可以是介面

  我們就根據輸入的引數來決定生產出哪種產品

  像這樣通過工廠類建立物件,且根據傳入的引數決定具體子類物件的做法,就是簡單工廠模式。

工廠方法模式

  但若我們需要新加新的口罩子類,口罩工廠的建立方法中就需要新增新的if-else判斷,這樣就不符合面向物件的開放-封閉原則。

  所謂面向物件的開放-封閉原則,就是在程式中對“擴充套件”開放,對“修改”封閉。如果每次業務改動都要增加新的if-else,就涉及對舊有程式碼的修改,不但容易出錯,可讀性也不好。

  想要解決這個問題,我們可以為每個口罩子類建立對應的工廠子類,這些工廠子類分別實現抽象的工廠介面。這樣一來,我們只需例項化不同的工廠子類,呼叫建立方法,得到的就是對應的口罩物件,這背後是面向物件的多型特性。

  根據這個思路,我們重構一下工廠,現在工廠是個介面,抽象方法是createMask。

  然後工廠有兩個子類——高階口罩工廠和低埠罩工廠

  他們實現了createMask方法

  在程式碼中,工廠類變成了抽象的介面,高階口罩工廠和低埠罩工廠這兩個子類分別實現了這兩個介面。

  在客戶端,想要建立什麼口罩物件,只需要例項化不同的工廠子類,然後呼叫他們的建立方法即可,無需再傳入引數。

  像這樣每一個口罩子類都對應一個工廠子類,利用多型性質動態建立物件的模式,就是工廠方法模式。

抽象工廠模式

  如果業務中我們要建立口罩,防毒面具,防護服三種產品,且每一種產品都包含高階到低端兩類,如果按照工廠方法模式建立工廠子類,就如下圖所示:

  當產品數量很多的時候,工廠類的數量也會越來越多,搞得非常複雜。

  那該怎麼辦呢——我們不需要為每一個產品配置一個工廠,而是可以把這些產品進行分組。對於上面的例子我們可以分成高階組和低端組,由同一個工廠類的不同方法建立。

  我們以口罩和防護服舉例,他們是兩個介面,分別由高階和低端兩個實現類:

publicinterfaceIMask{
voidshowMask();
}
 
publicclassLowEndMaskimplementsIMask{
@Override
publicvoidshowMask(){
System.out.println("我的低埠罩");
}
}
 
publicclassHighEndMaskimplementsIMask{
@Override
publicvoidshowMask(){
System.out.println("我是高階口罩");
}
}
 
publicinterfaceIProtectiveSuit{
voidshowSuit();
}
 
publicclassLowEndProtectiveSuitimplementsIProtectiveSuit{
@Override
publicvoidshowSuit(){
System.out.println("我是低端防護服");
}
}
 
publicclassHighEndProtectiveSuitimplementsIProtectiveSuit{
@Override
publicvoidshowSuit(){
System.out.println("我是高階防護服");
}
}

  然後是工廠類,因為產品分成了高階和低端兩個組,工廠也就分成了高階工廠和低端工廠,各自負責組內產品的建立:

publicinterfaceIFactory{
//建立口罩
IMaskcreateMask();
//建立防護服
IProtectiveSuitcreateSuit();
}
 
publicclassLowEndFactoryimplementsIFactory{
@Override
publicIMaskcreateMask(){
IMaskmask=newLowEndMask();
//.....
//LowEndMask的100行初始化程式碼
returnmask;
}
 
@Override
publicIProtectiveSuitcreateSuit(){
IProtectiveSuitsuit=newLowEndProtectiveSuit();
//.....
//LowEndProtectiveSuit的100行初始化程式碼
returnsuit;
}
}
 
publicclassHighEndFactoryimplementsIFactory{
@Override
publicIMaskcreateMask(){
IMaskmask=newHighEndMask();
//.....
//HighEndMask的100行初始化程式碼
returnmask;
}
 
@Override
publicIProtectiveSuitcreateSuit(){
IProtectiveSuitsuit=newHighEndProtectiveSuit();
//.....
//HighEndProtectiveSuit的100行初始化程式碼
returnsuit;
}
}

  然後我們寫test類,通過例項化不同工廠子類,呼叫不同建立方法,就可以創建出不同的產品:

  像這樣把產品分組,組內不同的產品對應同一工廠的不同方法的設計模式,就叫做抽象工廠模式。

總結

  •簡單工廠模式有唯一的工廠類,工廠類的建立方法根據傳入的引數做if-else條件判斷,決定最終建立什麼樣的產品物件。

  •工廠方法模式由多個工廠類實現工廠介面,利用多型來建立不同的產品物件,從而避免了冗長的if-else條件判斷。

  •抽象工廠模式把產品子類進行分組,同組中的不同產品由同一個工廠子類的不同方法負責建立,從而減少了工廠子類的數量。

reference

  程式設計師小灰:https://blog.csdn.net/bjweimengshu/article/details/108591085

        https://blog.csdn.net/bjweimengshu/article/details/108459337