建立對象_工廠方法(Factory Method)模式 與 靜態工廠方法

 

工廠方法模式:

 
定義:爲建立對象定義一個接口,讓子類決定實例化哪一個類。工廠方法讓一個類的實例化延遲至子類。
 
應用場景
  • 客戶類不關心使用哪一個具體類,只關心該接口所提供的功能;
  • 建立過程比較複雜,例如須要初始化其餘關聯的資源類,讀取配置文件等;
  • 接口有不少具體實現或者抽象有不少具體子類時,你可能須要爲客戶代碼寫一大串 if-else 邏輯來決定運行時使用哪一個具體實現或者具體子類;
  • 不但願給客戶程序暴露過多此類的內部結構,隱藏這些細節能夠下降耦合度;
  • 優化性能,好比緩存大對象或者初始化比較耗時的對象。
 
 
 
工廠方法模式
 
//工廠接口定義了 createProduct()方法來放回 Product 類型的實例對象
public interface Factory {
 
    // 若是具體實現較多,定義一個參數化的工廠方法,根據不一樣的參數返回不一樣的子類
    Product createProduct(String type);
}
 
//工廠接口實現類
public class ConcreteFactory implements Factory {
 
    // 若是具體實現較多,定義一個參數化的工廠方法,根據不一樣的參數返回不一樣的子類
    @Override
    public Product createProduct(String type) {
        if ("type1".equals(type)) {
            return new ConcreteProduct1();
        } else if ("type2".equals(type)) {
            return new ConcreteProduct2();
        } else {
            return new ConcreteProduct3();
        }
    }
}
 
//定義產品統一接口
public interface Product {
 
}
//不一樣的產品實現
public class ConcreteProduct1 implements Product {
 
}
public class ConcreteProduct2 implements Product {
 
}
public class ConcreteProduct3 implements Product {
 
}
 
    客戶類經過工廠獲得產品實例:
public class Client {
 
    private Factory factory;
 
    public Client(Factory factory) {
        this.factory = factory;
    }
 
    public void dosomething(String type) {
        Product product = factory.createProduct(type);
        // to do something
    }
 
    public static void main(String[] args) {
        // 實例化工廠
        Client client = new Client(new ConcreteFactory());
        // 傳入參數給工廠獲得指定的產品實例
        client.dosomething("type1");
    }
}

 

靜態工廠方法:

 
應用場景:工廠模式爲每一個類建立一個工廠方法 方法類會引發工廠類的泛濫。
 
解決方案:使用靜態工廠方法來避免——在每一個類裏實現一個靜態的工廠方法,就再也不須要額外的工廠類。
 
靜態工廠方法的優缺點
  • 優勢:
    • 能夠爲靜態工廠選擇合適的命名,提升程序的可讀性。
    • 靜態工廠和工廠模式同樣,能夠封裝複雜的初始化過程,實現實例的緩存。
    • 還能夠根據不一樣的輸入返回不一樣實現類/具體類對象。
  • 缺點:
    • 通常爲了強迫使用工廠方法,不直接使用構造方法來構造實例,咱們會強迫類只含有私有或是default的構造方法,這樣,會致使此類不能被子類化。
    • 若是添加了一個新的該類的子類(該類有非私有的構造方法),此靜態工廠方法可能須要重寫,以加入該子類的實例化過程,致使擴展性不強。
    • 靜態方法沒有面向對象的特徵,好比繼承、動態多態等,不可被覆寫(Overwritten)。
    • 採用構造函數實例化對象,是語言的規範,而靜態工廠方法與其餘的靜態方法沒有區別,就增長了用戶使用的區別。但這能夠儘可能採用一些家喻戶曉的名字解決,讓用戶看到更名字就知道該方法是靜態工廠方法。如getInstance( )。
    • 靜態工廠方法表明了一種對規範的背離。
 
    建立類的實例最多見的是new 除此外還可使用靜態工廠方法,來封裝實例的細節,而且能控制實例的數量,減輕 jvm的堆棧中的壓力。
 
 
靜態工廠方法與用 new語句調用的構造方法相比,有如下區別:
  • 使程序具備更好的可讀性。靜態工廠方法能夠突破構造函數不能自由命名的限制,對於不一樣的工廠方法能夠採用不一樣的會意的名字。JAVA平臺庫的java.text.Format的子類NumberFormat就有getInstance() , getPrecentInstance() , getCurrencyInstatnce()等靜態方法,經過不一樣的名字產生特定的對象。
  • 加大了程序設計和使用的靈活行。靜態工廠方法是用來產生對象用的,至於產生什麼類型的對象沒有限制,這就意味這隻要返回原返回類型或原返回類型的子類型均可以;或者是否會建立一個新的對象徹底取決於方法的實現。如java.util集合框架就採用了這種優點,這樣就能夠更好達到封裝的目的,下降API的數目和用戶的使用難度,java.util.Connections是集合框架的輔助類用於對原有的集合類進行進一步封裝,產生一些同步的集合,不可修改的視圖。都是採用靜態工廠方法實現的,至於方法內部的實現類就徹底別封裝了。也迫使咱們使用接口編程。
  • 解耦。靜態工廠方法所建立的對象能夠在編譯時不存在,動態建立對象,採用反射,相似Spring 的 IOC容器方轉。達到對象的建立與使用分離,使對象的客戶和對象之間解耦,增長程序的靈活性和可擴展性。
    靜態工廠方法最主要的特色是:每次被調用的時候,不必定要建立一個新的對象。利用這一特色,靜態工廠方法可用來建立如下類的實例。
  • 單例類:只有唯一的實例的類。
  • 枚舉類:實例的數量有限的類。
  • 具備實例緩存的類:能把已經建立的實例暫且存放在緩存中的類。
  • 具備實例緩存的不可變類:不可變類的實例一旦建立,其屬性值就不會被改變。
 
所謂靜態工廠方法(static factory method),實際上只是一個簡單的靜態方法,它返回的是類的一個實例。
public   static  Boolean  getTrue () {
     return  Boolean.TRUE;
}

 

 
總結:工廠模式把對象實例化的過程進行了封裝,客戶對象沒必要爲實例化而考慮更多,分離了實例化的邏輯,使得對象間的耦合性大大下降。
相關文章
相關標籤/搜索