1、前言
上篇文章 《Java 設計模式之工廠模式(二)》,介紹了簡單工廠模式和工廠方法模式,本篇將繼續介紹工廠模式中的最後一個模式–抽象工廠模式。java
2、簡單介紹
抽象工廠模式是全部形態的工廠模式中最爲抽象的。抽象工廠模式能夠向客戶端提供一個接口,使得客戶端在沒必要指定產品的具體類型(不是指實現類)的狀況下,可以建立多個產品族的產品對象。編程
產品族能夠通入下圖理解:設計模式
在上圖中,有多個發動機、輪胎和座椅,它們均可以看做是單獨的產品,咱們將發動機、輪胎和座椅組成一個產品族,用於區分其餘的發動機、輪胎和座椅。安全
每一個產品族又能夠劃分紅高端、中端和低端系列產品。ide
3、實現方式
咱們如今經過代碼實現不一樣產品族中每一個產品的建立。咱們以高端和低端產品族爲例。spa
發動機接口和實現類:.net
public interface Engine { void run(); } class HighEndEngine implements Engine { @Override public void run() { System.out.println("高端發動機,啓動快"); } } class LowEndEngine implements Engine { @Override public void run() { System.out.println("低端發動機,啓動慢"); } }
輪胎接口和實現類:設計
public interface Tyre { void use(); } class HighEndTyre implements Tyre { @Override public void use() { System.out.println("高端輪胎,耐磨防滑"); } } class LowEndTyre implements Tyre { @Override public void use() { System.out.println("低端輪胎,磨損大,易打滑"); } }
座椅接口和實現類:code
public interface Seat { void feel(); } class HighEndSeat implements Seat { @Override public void feel() { System.out.println("高端座椅,坐着溫馨"); } } class LowEndSeat implements Seat { @Override public void feel() { System.out.println("低端座椅,坐舊難受"); } }
工廠模式的前提:建立的實例一般都具備共同的父類,此處使用接口做爲「父類」。對象
若是使用工廠方法模式,代碼以下:
public interface EngineFactory { Engine createEngine(); } public interface TyreFactory { Tyre createTyre(); } public interface SeatFactory{ Seat createSeat(); } ...
客戶端調用:發動機、輪胎、座椅 3 個產品須要建立 3 個抽象工廠與 6 個實現類(高端和低端)。
public class Client { public static void main(String[] args) { EngineFactory ef = new HighEndEngineFactory(); Engine engine = ef.createEngine(); TyreFactory tf = new HighEndTyreFactory(); Tyre tyre = tf.createTyre(); SeatFactory sf = new HighEndEngineSeatFactory(); Seat seat = sf.createSeat(); } }
若是須要拼裝一輛高端的轎車,客戶端須要建立 3 個高端的工廠獲取發動機、輪胎和座椅才能完成需求。這樣客戶端就與多個類進行耦合,違反了迪米特法則。
假設,高端產品族新增一個安全鎖的產品,咱們又要新建相應的抽象工廠和子類工廠,項目結構的複雜度大大增長。所以,簡單工廠模式和工廠方法模式只適用於建立某一類對象,對於產品族維度劃分的產品建立的操做就顯得繁瑣了。
若是使用抽象工廠模式,咱們站在產品族內部結構的角度思考,抽象工廠中方法對應產品結構,而具體工廠對應產品族中的各個產品,那麼需求實現起來就輕鬆許多了。
工廠接口:
public interface CarFactory { Engine createEngine(); Tyre createTyre(); Seat createSeat(); }
工廠實現類:
public class HighEndCarFactory implements CarFactory { @Override public Engine createEngine() { return new HighEndEngine(); } @Override public Tyre createTyre() { return new HighEndTyre(); } @Override public Seat createSeat() { return new HighEndSeat(); } } public class LowEndCarFactory implements CarFactory { @Override public Engine createEngine() { return new LowEndEngine(); } @Override public Tyre createTyre() { return new LowEndTyre(); } @Override public Seat createSeat() { return new LowEndSeat(); } }
客戶端調用:
public class Client { public static void main(String[] args) { CarFactory cf = new HighEndCarFactory(); Engine engine = cf.createEngine(); Tyre tyre = cf.createTyre(); Seat seat = cf.createSeat(); } }
這種實現方式對應上文的內容:客戶端在沒必要指定產品的具體類型(發動機、輪胎、座椅)的狀況下,可以建立多個產品族的產品對象。當產品族中新增幾個產品,只需建立產品類以及在對應的工廠類中添加對應的方法便可。
在使用設計模式時,很難遵循五大原則和一大法則。咱們使用設計模式是爲了讓代碼具備可複用性、可擴展性和靈活性,不能一味地守着這幾個規定,從而限制本身對編程的想象和發揮。所以,須要使用怎樣的設計模式還得根據項目的實際需求來衡量選擇。