一.簡單工廠模式
簡單工廠模式就是把對類的建立初始化全都交給一個工廠來執行,而使用者不需要去關心建立的過程是什麼樣的,只用告訴工廠我想要什麼就行了。而這種方法的缺點也很明顯,違背了設計模式的開閉原則,因為如果你要增加工廠可以初始化的類的時候,你必須對工廠進行改建
程式碼如下:
package com.long88.ad.test; interface Car { public void getCar(); }
package com.long88.ad.test; public class BMW implements Car{ @Override public void getCar() { System.out.printf("來一輛BMW!"); } }
package com.long88.ad.test; public class BYD implements Car { @Override public void getCar() { System.out.printf("來一輛BYD!"); } }
package com.long88.ad.test; public class CarFactor { public static Car carFactor(Class<?> tClass){ if (tClass.getName().equals(BMW.class.getName())){ return new BMW(); } if (tClass.getName().equals(BYD.class.getName())){ return new BYD(); } return null; } }
package com.long88.ad.test; public class testFactory { public static void main(String[] args) { Car car = CarFactor.carFactor(BYD.class); car.getCar(); } }
結果如圖:
二. 工廠方法模式
設計一個工廠的介面,你想要什麼東西,就寫個類繼承於這個工廠,這樣就不用修改什麼,直接新增就行了。就相當於,我這個工廠是用來生汽車的,而要什麼品牌的汽車具體分到了每個車間,如果新多了一種品牌的汽車,直接新增一個車間就行了。那麼問題又來了,如果想要生產大炮怎麼辦?
程式碼如下:
package com.long88.ad.test; interface Car { public void getCar(); }
package com.long88.ad.test; public class BMW implements Car{ @Override public void getCar() { System.out.printf("來一輛BMW!"); } }
package com.long88.ad.test; public class BYD implements Car { @Override public void getCar() { System.out.printf("來一輛BYD!"); } }
//抽象工廠 interface CarFactory{ public Car getCarByFactory(); }
// BMW 具體工廠類 class BMWfactory implements CarFactory{ @Override public Car getCarByFactory() { return new BMW(); } }
// BYD 具體工廠類 class BYD factory implements CarFactory{ @Override public Car getCarByFactory() { return new BYD (); } }
public class TestFactory { public static void main(String[] args) { Car bmw= new BMWfactory().getCarByFactory(); bmw.getCar(); } }
三. 抽象工廠模式
定義:為建立一組相關或相互依賴的物件提供一個介面,而且無需指定他們的具體類。
抽象工廠與工廠方法的區別,就在於產品簇的問題,多了一種產品,這時候怎麼辦呢,就是在介面類裡面加上建立大炮的方法,然後每個車間就可以有兩個子車間分別來生產汽車和大炮。這樣的話缺點也很顯然的冒了出來,如果我又想生產飛機,那麼我要需要更改所有的工廠車間以及工廠介面。
抽象工廠模式是工廠方法模式的升級版本,他用來建立一組相關或者相互依賴的物件。他與工廠方法模式的區別就在於,工廠方法模式針對的是一個產品等級結構;而抽象工廠模式則是針對的多個產品等級結構。在程式設計中,通常一個產品結構,表現為一個介面或者抽象類,也就是說,工廠方法模式提供的所有產品都是衍生自同一個介面或抽象類,而抽象工廠模式所提供的產品則是衍生自不同的介面或抽象類。
程式碼如下:
package com.long88.ad.test; interface Car { public void getCar(); }
package com.long88.ad.test; public class BMW implements Car{ @Override public void getCar() { System.out.printf("來一輛BMW!"); } }
package com.long88.ad.test; public class BYD implements Car { @Override public void getCar() { System.out.printf("來一輛BYD!"); } }
package com.long88.ad.test; interface Plane{ public void getPlane(); }
package com.long88.ad.test; public class AirPlane implements Plane{ @Override public void getPlane() { System.out.printf("來一架客機!"); } }
package com.long88.ad.test; public class BattlePlane implements Plane{ @Override public void getPlane() { System.out.printf("來一架戰鬥機!"); } }
//抽象工廠 interface Factory{ public Car getCarByFactory();
public Plane getPlaneByFactory(); }
// 具體工廠類 class FactoryOne implements Factory{ @Override public Car getCarByFactory() { return new BMW(); } @Override public Plane getPlaneByFactory() { return new AirPlane(); } }
// 具體工廠類 class FactoryTwo implements Factory{ @Override public Car getCarByFactory() { return new BYD(); } @Override public Plane getPlaneByFactory() { return new BattlePlane (); } }
public class TestFactory { public static void main(String[] args) { Car byd = new FactoryTwo().getCarByFactory(); byd.getCar(); Plane airPlane = new FactoryOne().getPlaneByFactory(); airPlane.getPlane(); } } /* 執行結果 來一輛BYD! 來一架客機! */
使用場景
當我們直接new一個物件比較麻煩時,比如構造方法傳引數量太多;
再比如建立一個類A要先建立類B,這種使用new比較麻煩時就可以交給工廠去做,還減少了程式碼的重複。