工廠模式 前言 工廠模式又稱為創建模式,它是建對象的一種最佳方式。工廠模式的本質就是用工廠方法代替new操作創建一種實例化對象的方式。 在之前,如果我們想實例化一個對象Simple,一般會想到的方法就是通過構造器來創建Simple simple = new Simple(參數)。但是,如果創建sim ...
工廠模式
前言
工廠模式又稱為創建模式,它是建對象的一種最佳方式。工廠模式的本質就是用工廠方法代替new操作創建一種實例化對象的方式。
在之前,如果我們想實例化一個對象Simple,一般會想到的方法就是通過構造器來創建Simple simple = new Simple(參數)。但是,如果創建simple實例時所做的初始化工作不是像賦值這樣簡單的事,可能是很長一段代碼,那麼每當你需要創建simple這個對象的時候,你都需要寫這一段很長的代碼。這樣我們代碼的耦合性就會非常高。所以我們就需要將創建實例的工作和使用使用實例的工作分開,工廠模式會使用工廠方法將創建實例的工作封裝起來。這樣我們在需要調用對象的時候就不需要關心那些複雜的實例化問題。
簡單工廠模式
簡單工廠模式中有抽象產品類:用來定義具體產品的共有屬性,工廠類則負責生產具體產品。
假設我們需要生產不同品牌的手機
那麼我們可以先來定義一個Phone介面
public interface Phone {
String getBrand();
}
然後來創建兩個手機品牌:Apple和Huawei
public class Apple implements Phone {
public String getBrand() {
return "apple";
}
}
public class Huawei implements Phone {
public String getBrand() {
return "huawei";
}
}
定義一個工廠來生產手機
public class SimpleFactory {
public static Phone getPhone(String PhoneName){
if ("apple".equals(PhoneName)){
return new Apple();
}else if ("Huawei".equals(PhoneName)){
return new Huawei();
}
return null;
}
}
小結:
從簡單工廠中我們可以使用一個靜態方法將對象的創建和使用分離開。我們只需要調用方法傳遞參數就可以獲得我們需要的對象。
但我們會發現簡單工廠模式存在一系列問題:
- 工廠類集中了所有實例(產品)的創建邏輯,一旦這個工廠不能正常工作,整個系統都會受到影響;
- 違背“開放 - 關閉原則”,一旦添加新產品就不得不修改工廠類的邏輯,這樣就會造成工廠邏輯過於複雜。
- 簡單工廠模式由於使用了靜態工廠方法,靜態方法不能被繼承和重寫,會造成工廠角色無法形成基於繼承的等級結構。
為瞭解決上述的問題,我們又使用了一種新的設計模式:工廠方法模式。
工廠方法模式
工廠方法模式,又稱工廠模式、多態工廠模式和虛擬構造器模式,通過定義工廠父類負責定義創建對象的公共介面,而子類則負責生成具體的對象。
將類的實例化(具體產品的創建)延遲到工廠類的子類(具體工廠)中完成,即由子類來決定應該實例化(創建)哪一個類。
下麵我們將上面簡單工廠模式中生產手機的例子修改為使用工廠方法模式
創建抽象工廠類,定義具體工廠的公共介面
public abstract class PhoneFactory {
Phone getPhone();
}
創建具體工廠類(繼承抽象工廠類),定義創建對應具體產品實例的方法
public class AppleFactory extends PhoneFactory {
public Phone getPhone() {
return new Apple();
}
}
public class HuaweiFactory extends PhoneFactory {
public Phone getPhone() {
return new Huawei();
}
}
外界通過調用具體工廠類的方法,從而生產出不同手機
小結:
優點
- 更符合開-閉原則,即新增一種產品時,只需要增加相應的具體產品類和相應的工廠子類即可;
- 符合單一職責原則,每個具體工廠類只負責創建對應的產品;
- 不使用靜態工廠方法,可以形成基於繼承的等級結構;
缺點
添加新產品時,除了增加新產品類外,還要提供與之對應的具體工廠類,系統類的個數將成對增加,在一定程度上增加了系統的複雜度;同時,有更多的類需要編譯和運行,會給系統帶來一些額外的開銷;
雖然保證了工廠方法內的對修改關閉,但對於使用工廠方法的類,如果要更換另外一種產品,仍然需要修改實例化的具體工廠類;
抽象工廠模式
抽象工廠是所有形態的工廠模式中最為抽象和最具一般性的一種形態。抽象工廠是指當有多個抽象角色時使用的一種工廠模式。抽象工廠模式可以向客戶端提供一個介面,使客戶端在不必指定產品的具體情況下,創建多個產品族中的產品對象。
抽象工廠模式相對於工廠方法模式來說,就是工廠方法模式是針對一個產品系列的,而抽象工廠模式是針對多個產品系列的,即工廠方法模式是一個產品系列一個工廠類,而抽象工廠模式是多個產品系列一個工廠類。
假設我們有兩個產品介面Phone和Computer,每一種產品都支持多種系列,比如Apple和Huawei系列。這樣每個系列的產品分別是Iphone、Huawei、MacBook、MateBook。為了可以在運行時刻創建一個系列的產品族,我們可以為每個系列的產品族創建一個工廠 AppleFactory和 HuaweiFactory。每個工廠都有兩個方法 getPhone 和 getComputer 並返回對應的產品,可以將這兩個方法抽象成一個介面 AbstractFactory 。這樣在運行時刻我們可以選擇創建需要的產品系列。
具體代碼:
AbstractFactory:
public abstract class AbstractFactory {
public abstract Phone getPhone();
public abstract Computer getComputer();
}
AppleFactory:
public class AppleFactory extends AbstractFactory {
public Phone getPhone() {
return new Iphone();
}
public Computer getComputer() {
return new MacBook();
}
}
HuaweiFactory:
public class HuaweiFactory extends AbstractFactory {
public Phone getPhone() {
return new Huawei();
}
public Computer getComputer() {
return new MateBook();
}
}
小結:
優點
- 新增一種產品類時,只需要增加相應的具體產品類和相應的工廠子類即可;
- 不使用靜態工廠方法,可以形成基於繼承的等級結構
- 更符合開-閉原則,新增一種產品類時,只需要增加相應的具體產品類和相應的工廠子類即可
- 符合單一職責原則,每個具體工廠類只負責創建對應的產品
最後總結一下工廠方法模式和抽象工廠模式的區別:
- 工廠方法模式利用繼承,抽象工廠模式利用組合
- 工廠方法模式產生一類對象,抽象工廠模式產生一族對象
- 工廠方法模式利用子類創造對象,抽象工廠模式利用介面的實現創造對象