工廠模式出現的原因 在java中,創建一個對象最簡單的方法就是使用new關鍵字。但在一些複雜的業務邏輯中,創建一個對象不只需要new一行代碼就成了,可能需要一些列的初始化設置,或先創建一些輔助對象來創建這個對象。 在這種場景中,如果需要多次創建這種對象,那每次都要寫很多代碼。工廠模式的產生就是為瞭解 ...
Java設計模式之【工廠模式】(簡單工廠模式,工廠方法模式,抽象工廠模式)
工廠模式出現的原因
在java中,創建一個對象最簡單的方法就是使用new關鍵字。但在一些複雜的業務邏輯中,創建一個對象不只需要new一行代碼就成了,可能需要一些列的初始化設置,或先創建一些輔助對象來創建這個對象。
在這種場景中,如果需要多次創建這種對象,那每次都要寫很多代碼。工廠模式的產生就是為瞭解決這種問題。
工廠模式厲害之處就在於:你不需要知道創建對象的細節就可以輕鬆的創建你想要的對象,並且產品和工廠是解耦的。
3種工廠模式介紹
1、簡單工廠模式
1個具體工廠類,1個抽象產品類,多個具體產品類
每個工廠可以創建多個產品實例,當需要創建新產品的時候,需要修改工廠類,不符合java開閉原則
用戶需要什麼類型的產品,告訴工廠類,工廠類就創建什麼類型的產品實例
2、工廠方法模式
1個抽象工廠類,多個具體工廠類,1個抽象產品類,多個具體產品類
每個工廠只能創建1個產品實例,當需要創建新產品的時候,需要擴展抽象工廠類,而不需要修改,符合java開閉原則
用戶需要什麼類型的產品,就從什麼類型的工廠生產
3、抽象工廠模式
1個抽象工廠類,多個具體工廠類,多個抽象產品類,多個抽象產品類
每個工廠可以創建多個產品實例,當需要創建新產品的時候,需要擴展抽象工廠類,而不需要修改,符合java開閉原則
用戶需要什麼類型的產品,就從什麼類型的工廠生產
用於生產一組相關或者相互依賴的產品
下麵以工廠生產寶馬車為例子開始具體介紹這3種工廠模式
一、簡單工廠模式
需求:用戶需要寶馬車,並希望工廠根據自己提出的類型可以生產不同類型的寶馬車
public abstract class BMW {} public class BMW320 extends BMW {} public class BMW520 extends BMW {} public class BMWFactory { BMW createBMW(Integer type){ if(type == 320){ return new BMW320(); }else if(type == 520){ return new BMW520(); }else{ return null; } } } public class Customer { public static void main(String[] args) { BMWFactory bmwFactory = new BMWFactory(); BMW myBMW320 = bmwFactory.createBMW(320); //告訴工廠自己需要什麼類型的產品 BMW myBMW520 = bmwFactory.createBMW(520); } }
特點:產品和工廠完全耦合,當需要生產新產品的時候,必須修改工廠類的create()方法,違背了java對擴展開放,對修改關閉的原則
二、工廠方法模式
需求:我不希望只有一個工廠來生產所有的寶馬車,我希望每種寶馬車都由其對應的工廠來生產
public abstract class BMW {} public class BMW320 extends BMW {} public class BMW520 extends BMW {} public abstract class BMWFactory { abstract BMW createBMW(); } public class BMW320Factory extends BMWFactory { @Override BMW createBMW() { return new BMW320(); } } public class BMW520Factory extends BMWFactory { @Override BMW createBMW() { return new BMW520(); } } public class Customer { public static void main(String[] args) { BMWFactory bmw320Factory = new BMW320Factory(); BMWFactory bmw520Factory = new BMW520Factory(); BMW bmw320 = bmw320Factory.createBMW(); //需要什麼類型的產品,就從什麼類型的工廠來生成 BMW bmw520 = bmw520Factory.createBMW(); } }
類結構圖
特點:產品和工廠完全解耦,當需要生產新產品的時候,只需要擴展新工廠。弊端也很明顯,由於每種工廠只生產1中產品,隨著新產品越來越多,新工廠也會越來越多
三、抽象工廠模式
需求:用戶希望在不同類型的寶馬車上可以有不同類型的引擎或空調,如寶馬320中安裝引擎A和空調A,寶馬520中安裝引擎B和空調B
引擎類
public abstract class Engine { abstract public String show(); } public class EngineA extends Engine { @Override public String show() { return "EngineA"; } } public class EngineB extends Engine { @Override public String show() { return "EngineB"; } }
空調類
public abstract class AirCondition { abstract public String show(); } public class AirConditionA extends AirCondition { @Override public String show() { return "AirConditionA"; } } public class AirConditionB extends AirCondition { @Override public String show() { return "AirConditionB"; } }
寶馬車類
public abstract class BMW { private Engine engine; private AirCondition aircondition; public Engine getEngine() { return engine; } public void setEngine(Engine engine) { this.engine = engine; } public AirCondition getAircondition() { return aircondition; } public void setAircondition(AirCondition aircondition) { this.aircondition = aircondition; } public abstract String show(); } public class BMW320 extends BMW { @Override public String show() { return "我是BMW320,我的引擎:" + getEngine().show() + ",我的空調:" + getAircondition().show(); } } public class BMW520 extends BMW { @Override public String show() { return "我是BMW520,我的引擎:" + getEngine().show() + ",我的空調:" + getAircondition().show(); } }
工廠類
public abstract class BMWFactory { abstract BMW createBMW(); abstract Engine createEngine(); abstract AirCondition createAirCondition(); } public class BMW320Factory extends BMWFactory { @Override BMW createBMW() { BMW bmw320 = new BMW320(); Engine engineA = createEngine(); AirCondition airConditionA = createAirCondition(); bmw320.setEngine(engineA); bmw320.setAircondition(airConditionA); return bmw320; } @Override Engine createEngine() { return new EngineA(); } @Override AirCondition createAirCondition() { return new AirConditionA(); } } public class BMW520Factory extends BMWFactory { @Override BMW createBMW() { BMW bmw520 = new BMW520(); Engine engineB = createEngine(); AirCondition airConditionB = createAirCondition(); bmw520.setEngine(engineB); bmw520.setAircondition(airConditionB); return bmw520; } @Override Engine createEngine() { return new EngineB(); } @Override AirCondition createAirCondition() { return new AirConditionB(); } }
用戶類
public class Customer { public static void main(String[] args) { BMWFactory bmw320Factory = new BMW320Factory(); BMW bmw320 = bmw320Factory.createBMW(); System.out.println(bmw320.show()); BMWFactory bmw520Factory = new BMW520Factory(); BMW bmw520 = bmw520Factory.createBMW(); System.out.println(bmw520.show()); } }
類結構圖
運行結果
我是BMW320,我的引擎:EngineA,我的空調:AirConditionA
我是BMW520,我的引擎:EngineB,我的空調:AirConditionB
工廠方法模式和抽象工廠模式比較
工廠方法模式中,只有一個抽象產品類,每個工廠只能生產對應類型的產品實例
抽象工廠模式中,有多個抽象產品類,每個工廠可以生產多種類型的產品實例
總結
無論是哪種工廠模式,它們在形式和特點上都是相似的,他們的特點都是為了使產品和工廠解耦。在使用時不必在意具體是工廠方法模式還是抽象工廠模式,因為有時你會發現,明明使用的是工廠方法模式,當新需求來臨,對代碼稍加擴展或修改,加入一個新產品或方法後,由於產品構成了不同等級的產品族,就變成抽象工廠模式了。而在抽象工廠模式中,當減少一個產品或方法使得工廠提供的產品不再構成產品族後,它就演變成了工廠方法模式。
所以在使用工廠模式時,只需要關心是否降低了耦合度就ok了。
我的博客即將搬運同步至騰訊雲+社區,邀請大家一同入駐:https://cloud.tencent.com/developer/support-plan?invite_code=2biv3j8ly5xc8