工廠模式 當我們創建一個對象比較複雜時且客戶端不關心於實例對象的創建過程時我們可以用工廠模式 類型: 簡單工廠模式 工廠方法模式 抽象工廠模式 簡單工廠模式 工廠方法模式 抽象工廠模式 簡單工廠模式 簡單工廠模式是屬於創建型模式,又叫做靜態工廠方法(Static Factory Method)模式, ...
工廠模式
當我們創建一個對象比較複雜時且客戶端不關心於實例對象的創建過程時我們可以用工廠模式
類型:
-
簡單工廠模式
-
工廠方法模式
-
抽象工廠模式
簡單工廠模式
百度百科
簡單工廠模式是屬於創建型模式,又叫做靜態工廠方法(Static Factory Method)模式,但不屬於23種GOF設計模式之一。簡單工廠模式是由一個工廠對象決定創建出哪一種產品類的實例。簡單工廠模式是工廠模式家族中最簡單實用的模式,可以理解為是不同工廠模式的一個特殊實現
下麵我們來舉一個例子:
比如我們一個手機可能有蘋果、華為、小米這些品牌的手機,手機裡面又有很多零件,如果當一個手機的類定義是這樣的
public class Mobile implements IMobile{ //CPU private String cpu; //記憶體 private String memory; //顯示屏 private String display; public Mobile(String cpu, String memory, String display) { this.cpu = cpu; this.memory = memory; this.display = display; } public void show() { System.out.println(this.getDisplay() + " show..."); } }
手機類實現了一個介面IMobile 這個介面有一個方法show();
如果我們不用工廠模式呢可能我們生產一個手機是這樣的:
IMobile mobile = new Mobile("蘋果cpu","蘋果記憶體","蘋果顯示器"); mobile.show();
如果這樣的話我們使用者就需要知道我們創建一個Mobile需要傳入什麼參數,但如果我們使用簡單工廠模式的話就比較簡單了,首先我們定義一個工廠類:
public class MobileFactory { IMobile create(String name){ if("iphone".equals(name)){ return new Mobile("蘋果cpu","蘋果記憶體","蘋果顯示器"); }else if("xiaomi".equals(name)){ return new Mobile("小米cpu","小米記憶體","小米顯示器"); }else{ return null; } } }
該工廠類有一個創建方法,參數接受一個手機品牌的名稱,然後我們返回一個相應的手機實例,創建實例需要的參數我們在方法里定義好,這樣我們客戶端在創建手機實例的時候只需要傳入相應的品牌名稱就好了,不需要關心創建的邏輯和實現也就是我們例子中的所需要的參數:
public static void main(String[] args) { MobileFactory factory = new MobileFactory(); IMobile mobile = factory.create("iphone"); mobile.show(); }
這個就是我們的簡單工廠模式了,但是如果使用了簡單工廠的話我們來想下如果當我要新增一個產品的話要怎麼辦呢,比如我現在要新增一個華為手機,那我們就需要在簡單工廠中修改創建方法的邏輯,增加一個華為品牌的創建邏輯,這樣就不符合我們的開閉原則了,同時如果我們的品牌非常多的話創建方法就會太複雜太重了,這樣不利於我們的維護。
優缺點
優點:
只需傳入一個工廠類的參數,無需關心我們的創建流程
缺點:
工廠類的職責過重,新增產品需要修改工廠類的方法,違背了我們的開閉原則,不易於擴展比較複雜的產品結構
適合場景
工廠類只需要創建很少的對象,客戶端不需要傳入工廠參數,不需要關心創建流程
工廠方法模式
維基百科
工廠方法模式(英語:Factory method pattern)是一種實現了“工廠”概念的面向對象設計模式。就像其他創建型模式一樣,它也是處理在不指定對象具體類型的情況下創建對象的問題。工廠方法模式的實質是“定義一個創建對象的介面,但讓實現這個介面的類來決定實例化哪個類。工廠方法讓類的實例化推遲到子類中進行
工廠方法模式是可以用來解決我們上面簡單工廠模式的缺點的,工廠方法模式是簡單工廠的一個升級,我們還是用上面的例子來看下工廠方法模式是怎麼實現的,首先,我們先定義一個工廠類的介面:
public interface IMobileFactory { IMobile create(); }
該介面只有一個方法create,返回一個手機實例,我們再來根據品牌創建一個工廠介面的實現類,我們先創建一個蘋果品牌的實現類:
public class IPhoneFactory implements IMobileFactory { public IMobile create() { return new Mobile("蘋果cpu","蘋果記憶體","蘋果顯示器"); } }
這樣我們的客戶端在使用的時候只需要指定具體的工廠類就可以了:
public static void main(String[] args) { IMobileFactory factory = new IPhoneFactory(); IMobile mobile = factory.create(); mobile.show(); }
如果我們需要新增品牌的時候只需要增加新的品牌工廠就行了,比如我們來新增小米的工廠類:
public class XiaoMiFactory implements IMobileFactory { public IMobile create() { return new Mobile("小米cpu","小米記憶體","小米顯示器"); } } public static void main(String[] args) { IMobileFactory factory = new XiaoMiFactory(); IMobile mobile = factory.create(); mobile.show(); }
這樣我們就避免了新增產品的時候需要去修改工廠方法了,符合了我們的開閉原則。
優缺點
優點:
不需要關心產品的創建流程,只需關心產品對應的工廠,新增產品時易於擴展,符合開閉原則
缺點:
當品牌過多的時候會生成過多的工廠類,增加了代碼結構的複雜性,增加系統的抽象性,不易於理解
適用場景
創建對象需要大量的重覆代碼時,不關心創建細節,通過子類去指定創建哪個對象
抽象工廠模式
維基百科
抽象工廠模式(英語:Abstract factory pattern)是一種軟體開發設計模式。抽象工廠模式提供了一種方式,可以將一組具有同一主題的單獨的工廠封裝起來。在正常使用中,客戶端程式需要創建抽象工廠的具體實現,然後使用抽象工廠作為介面來創建這一主題的具體對象。客戶端程式不需要知道(或關心)它從這些內部的工廠方法中獲得對象的具體類型,因為客戶端程式僅使用這些對象的通用介面。抽象工廠模式將一組對象的實現細節與他們的一般使用分離開來。
我們還是按上面的例子來說,比如現在我們的蘋果和小米不止有手機了,還有其對應的筆記本電腦、運動手環啊之類的,這樣每個品牌下都有自己對應的產品,我們就可以用抽象工廠來實現,首先我們還是創建一個工廠介面,該介面下有對應的創建產品的方法:
public interface IMobileFactory { //生產手機 IMobile createMobile(); //生產電腦 IComputer createComputer(); //生產手環 IBracelet createBracelet(); }
接下來我們就要來實現對應品牌下的工廠類:
public class IPhoneFactory implements IMobileFactory{ public IMobile createMobile() { return new Mobile("蘋果cpu","蘋果記憶體","蘋果顯示器"); } public IComputer createComputer() { return new Computer("蘋果"); } public IBracelet createBracelet() { return new Bracelet("蘋果"); } } public class XiaoMiFactory implements IMobileFactory { public IMobile createMobile() { return new Mobile("小米cpu","小米記憶體","小米顯示器"); } public IComputer createComputer() { return new Computer("小米"); } public IBracelet createBracelet() { return new Bracelet("小米"); } }
這樣,我們客戶端在創建對應品牌下的產品的時候只需要關心對應的工廠類就可以了:
public static void main(String[] args) { //蘋果創建 IMobileFactory factory = new IPhoneFactory(); factory.createComputer().start(); factory.createBracelet().show(); factory.createMobile().show(); //小米創建 factory = new XiaoMiFactory(); factory.createComputer().start(); factory.createBracelet().show(); factory.createMobile().show(); }
優缺點
優點:
具體創建的產品在應用層隔離,無需關心創建細節,一系列的品牌產品在統一到一起創建
缺點:
當品牌需要新增產品的時候,所以實現該介面的工廠類都需要修改,修改困難,需要在定義的時候先規定好產品集合
適合場景