前言
工廠模式是最常用的一類建立型設計模式,主要是簡單工廠模式、抽象工廠模式,工廠方法模式 這三種。後續詳細介紹每一種工廠模式。
簡單工廠模式
定義簡單工廠模式是指由一個工廠物件決定創建出哪一種產品類的例項。簡單工廠模式中用於建立實 例的方法是靜態的,因此簡單工廠模式又被稱為靜態工廠方法模式。
簡單工廠模式不屬於GOF 23種設計模式
示例模擬電腦產品
首先定義一個電腦產品介面
public interface Computer { public void show();}
定義華碩品牌電腦
/** * 華碩 */public class ASUS implements Computer { @Override public void show() { System.out.println("this is ASUS computer"); }}
定義聯想品牌電腦
/** * 聯想 */public class Lenovo implements Computer { @Override public void show() { System.out.println("this is lenovo computer"); }}
定義惠普品牌電腦
/** * 惠普 */public class HP implements Computer { @Override public void show() { System.out.println("this is HP computer"); }}
定義工廠
public class ComputerFactory { /** * 透過條件判斷 new 物件 * @param name * @return */ static Computer createComputer(String name) { switch (name) { case "Lenovo": return new Lenovo(); case "ASUS": return new ASUS(); case "HP": return new HP(); default: return null; } } /** * 透過反射,傳遞類的全路徑名 * @param className * @return */ static Computer createComputerReflect(String className) { try { Computer computer = (Computer) Class.forName(className).newInstance(); return computer; } catch (Exception e) { e.printStackTrace(); } return null; } /** * 透過反射,限定class類 * @param clazz * @return */ static Computer createComputer(Class<? extends Computer> clazz) { try { Computer computer = (Computer) clazz.newInstance(); return computer; } catch (Exception e) { } return null; }}
測試類程式碼
public class Main { public static void main(String[] args) { Computer lenovo = ComputerFactory.createComputer("Lenovo"); lenovo.show(); Computer HP = ComputerFactory.createComputerReflect ("com.chao.design.pattern.factory.model.HP"); HP.show(); Computer asus = ComputerFactory.createComputer(ASUS.class); asus.show(); }}
執行結果如下圖
適用場景工廠類負責建立的物件比較少;客戶端只需要傳入工廠類的引數,對於如何建立物件的邏輯不需要關心;優點只需要傳入一個正確的引數就可以獲取所需要的物件,無須關心建立的細節。
缺點 工廠類的職責相對過重,增加新的產品時需要修改工廠類的判斷邏輯,違背開閉原則。 不易於擴充套件過於複雜的產品結構。工廠方法模式
定義定義一個建立物件的介面,讓實現這個介面的類(子類)決定例項化將哪一個類。工廠方法模式將類的例項化延遲到子類中進行。
與簡單工廠模式相比,工廠方法 模式引入了抽象工廠角色,抽象工廠可以是介面,也可以是抽象類。
示例繼續使用電腦產品場景。
定義抽象工廠
public interface IComputerFactory { Computer create();}
定義聯想電腦工廠,實現抽象工廠。
public class LenovoFactory implements IComputerFactory { @Override public Computer create() { return new Lenovo(); }}
定義華碩電腦工廠,實現抽象工廠。
public class ASUSFactory implements IComputerFactory { @Override public Computer create() { return new ASUS(); }}
客戶端類,需要什麼品牌電腦則透過電腦對應的工廠類來獲取即可 。
public class Main { public static void main(String[] args) { LenovoFactory lenovoFactory = new LenovoFactory(); Computer lenovo = lenovoFactory.create(); lenovo.show(); ASUSFactory asusFactory = new ASUSFactory(); Computer asus = asusFactory.create(); asus.show(); }}
當需要增加一個品牌電腦時,只需要增加具體電腦類和具體工廠類即可,不需要修改原有的電腦類和工廠類。例如 增加惠普電腦工廠。
public class HPFactory implements IComputerFactory { @Override public Computer create() { return new HP(); }}
客戶端呼叫程式碼
public class Main { public static void main(String[] args) { LenovoFactory lenovoFactory = new LenovoFactory(); Computer lenovo = lenovoFactory.create(); lenovo.show(); ASUSFactory asusFactory = new ASUSFactory(); Computer asus = asusFactory.create(); asus.show(); HPFactory hpFactory = new HPFactory(); Computer hp = hpFactory.create(); hp.show(); }}
適用場景建立物件需要大量重複的程式碼。客戶端不依賴於產品類例項如何被建立,實現等細節。抽象工廠類透過其子類來指定建立哪個物件。優點使用者只需要關心產品對應的工廠,無需關心建立細節。加入新產品符合開閉原則,提高了系統的可擴充套件性。缺點類的數量容易過多,增加了程式碼結構的複雜度。增加了系統的抽象性和理解難度。抽象工廠模式
定義提供一個建立一系列相關或相互依賴物件的介面,無須指定它們具體的類。
在抽象工廠模式中,每一個具體工廠都提供了多個工廠方法用於產生多種不同型別的產品。
具體工廠實現了抽象工廠,每一個具體的工廠方法可以返回一個特定的產品物件,而同一個具體 工廠所建立的產品物件構成了一個產品族。
示例繼續使用上面定義的電腦產品,增加滑鼠產品。
定義抽象滑鼠介面
public interface Mouse { public void show();}
定義聯想滑鼠
/** * 聯想 */public class Lenovo implements Mouse { @Override public void show() { System.out.println("this is lenovo mouse"); }}
定義華碩滑鼠
/** * 華碩 */public class ASUS implements Mouse { @Override public void show() { System.out.println("this is ASUS mouse"); }}
定義抽象工廠,與工廠方法模式不同,工廠方法模式中一個工廠只生產一個產品,而抽象工廠模式中一個工廠生產一族產品,有多個工廠方法。如下程式碼
public interface IProductFactory { /** * 生產電腦 * @return */ Computer createComputer(); /** * 生產滑鼠 * @return */ Mouse createMouse();}
定義具體工廠,具體工廠都實現了抽象工廠。
public class LenovoFactory implements IProductFactory { @Override public Computer createComputer() { return new Lenovo(); } @Override public Mouse createMouse() { return new LenovoMouse(); }}
public class ASUSFactory implements IProductFactory { @Override public Computer createComputer() { return new ASUS(); } @Override public Mouse createMouse() { return new ASUSMouse(); }}
客戶端只需要指定具體工廠,就可以獲取該工廠生產的族產品。
public class Main { public static void main(String[] args) { LenovoFactory lenovoFactory = new LenovoFactory(); Computer lenovoComputer = lenovoFactory.createComputer(); Mouse lenovoMouse = lenovoFactory.createMouse(); lenovoComputer.show(); lenovoMouse.show(); ASUSFactory asusFactory = new ASUSFactory(); Computer asusComputer = asusFactory.createComputer(); Mouse asusMouse = asusFactory.createMouse(); asusComputer.show(); asusMouse.show(); }}
執行結果如下圖
適用場景強調一系列的產品物件(屬於同一產品族)一起使用建立物件需要大量重複的程式碼。提供一個產品類的庫,所有的產品以同樣的接口出現,從而使客戶端不依賴於具體實現。優點具體產品在應用層程式碼隔離,無需關心建立細節。將一個系列的產品族統一到一起建立。缺點規定了所有可能被建立的產品集合,產品族中擴充套件新的產品困難,需要修改抽象工廠的介面,違背了開閉原則。增加了系統的抽象性和理解難度。以上就是個人對工廠模式的理解。歡迎大家提出不同的觀點。