天天看點

java設計模式——工廠方法模式(Factory Method Pattern)

       簡單工廠模式雖然簡單,但也受到很大限制,擴充性太差,當系統中需要引入新産品時, 由于靜态工廠方法通過所傳入參數的不同來建立不同的産品,這必定要修改工廠類的源代碼,将違背“開閉原則”, 如何實作增加新産品而不影響已有代碼?工廠方法模式應運而生,本文将介紹第二種工廠模式——工廠方法模式。

定義:工廠方法模式(Factory Method Pattern)又稱為工廠模式,也叫虛拟構造器(Virtual Constructor)模式或者多态工廠(Polymorphic Factory)模式,它屬于類建立型模式。 在工廠方法模式中,工廠父類負責定義建立産品對象的公共接口,而工廠子類則負責生成具體的産品對象,這樣做的目的是将産品類的執行個體化操作延遲到工廠子類中完成, 即通過工廠子類來确定究竟應該執行個體化哪一個具體産品類。

結構:

  • Product:抽象産品 , 它是具體産品繼承的父類或者是實作的接口。在java中一般有抽象類或者接口來實作。 
  • ProductA:具體産品 ,它實作了抽象産品接口,某種類型的具體産品由專門的具體工廠建立,具體工廠和具體産品之間一一對應。
  • Factory:抽象工廠 ,這是工廠方法模式的核心,它與應用程式無關。是具體工廠角色必須實作的接口或者必須繼承的父類。在java中它由抽象類或者接口來實作。
  • FactoryA:具體工廠,它是抽象工廠類的子類,實作了抽象工廠中定義的工廠方法,并可由用戶端調用,傳回一個具體産品類的執行個體。

具體結構圖:

java設計模式——工廠方法模式(Factory Method Pattern)

工廠類:

public interface Factory {

    public Product createProduct();

}

public class FactoryA implements Factory {     @Override

    public ProductA createProduct() {

        return new ProductA();

    }

}

public class FactoryB implements Factory {

    @Override

    public ProductB createProduct() {

        return new ProductB();

    }

}

用戶端調用: FactoryA factoryA = new FactoryA();

ProductA productA = factoryA.createProduct();

FactoryB factoryB = new FactoryB();

ProductB productB = factoryB.createProduct();

産品類(同簡單工廠模式代碼): http://blog.csdn.net/yj_android_develop/article/details/52024698

工廠方法模式優點:

  • 在工廠方法模式中,工廠方法用來建立客戶所需要的産品,同時還向客戶隐藏了哪種具體産品類将被執行個體化這一細節, 使用者隻需要關心所需産品對應的工廠,無須關心建立細節,甚至無須知道具體産品類的類名。
  • 基于工廠角色和産品角色的多态性設計是工廠方法模式的關鍵。它能夠使工廠可以自主确定建立何種産品對象, 而如何建立這個對象的細節則完全封裝在具體工廠内部。工廠方法模式之是以又被稱為多态工廠模式,是因為所有的具體工廠類都具有同一抽象父類。
  • 使用工廠方法模式的另一個優點是在系統中加入新産品時,無須修改抽象工廠和抽象産品提供的接口, 無須修改用戶端,也無須修改其他的具體工廠和具體産品,而隻要添加一個具體工廠和具體産品就可以了。這樣,系統的可擴充性也就變得非常好,完全符合“開閉原則”。

工廠方法模式缺點:

  • 在添加新産品時,需要編寫新的具體産品類,而且還要提供與之對應的具體工廠類,系統中類的個數将成對增加,在一定程度上增加了系統的複雜度, 有更多的類需要編譯和運作,會給系統帶來一些額外的開銷。
  • 由于考慮到系統的可擴充性,需要引入抽象層,在用戶端代碼中均使用抽象層進行定義,增加了系統的抽象性和了解難度, 且在實作時可能需要用到DOM、反射等技術,增加了系統的實作難度。

工廠方法使用環境:

  • 一個類不知道它所需要的對象的類:在工廠方法模式中,用戶端不需要知道具體産品類的類名,隻需要知道所對應的工廠即可, 具體的産品對象由具體工廠類建立;用戶端需要知道建立具體産品的工廠類。
  • 一個類通過其子類來指定建立哪個對象:在工廠方法模式中,對于抽象工廠類隻需要提供一個建立産品的接口, 而由其子類來确定具體要建立的對象,利用面向對象的多态性和裡氏代換原則,在程式運作時,子類對象将覆寫父類對象,進而使得系統更容易擴充。
  • 将建立對象的任務委托給多個工廠子類中的某一個,用戶端在使用時可以無須關心是哪一個工廠子類建立産品子類,需要時再動态指定, 可将具體工廠類的類名存儲在配置檔案或資料庫中。

模式擴充:

  • 使用多個工廠方法:在抽象工廠角色中可以定義多個工廠方法,進而使具體工廠角色實作這些不同的工廠方法,這些方法可以包含不同的業務邏輯, 以滿足對不同的産品對象的需求。
  • 産品對象的重複使用:工廠對象将已經建立過的産品儲存到一個集合(如數組、List等)中,然後根據客戶對産品的請求,對集合進行查詢。 如果有滿足要求的産品對象,就直接将該産品傳回用戶端;如果集合中沒有這樣的産品對象,那麼就建立一個新的滿足要求的産品對象, 然後将這個對象在增加到集合中,再傳回給用戶端。

工廠方法模式和簡單工廠模式差別:

  • 工廠方法模式是在工廠模式的基礎上對工廠類進行抽象,使系統的擴充性變得更好,完全符合“開閉原則”;
  • 如果工廠方法模式中工廠等級結構隻有傳回一個具體工廠的話,則抽象工廠可以省略,當隻有一個具體工廠,在具體工廠中可以建立所有的産品對象,并且工廠方法設計為靜态方法時,工廠方法模式就退化成簡單工廠模式。

抽象工廠模式:http://blog.csdn.net/yj_android_develop/article/category/6329781

繼續閱讀