Java設計模式(二):工廠方法模式

起個名字好難__發表於2020-10-07

模式動機

上文中,我們瞭解到簡單工廠模式的動機,優點與缺點。簡單工廠模式中,工廠類擔負的責任過重,如果要新增具體產品就必須對工廠類進行重新實現,沒有滿足開閉原則。
在工廠方法中,建立了工廠的抽象類,當需要新增具體產品時,只需要針對相應的具體產品新增對應的工廠類即刻。

模式定義

工廠方法模式(Factory Method Pattern)又稱為工廠模式,也叫虛擬構造器(Virtual Constructor)模式或者多型工廠(Polymorphic Factory)模式,它屬於類建立型模式。在工廠方法模式中,工廠父類負責定義建立產品物件的公共介面,而工廠子類則負責生成具體的產品物件,這樣做的目的是將產品類的例項化操作延遲到工廠子類中完成,即通過工廠子類來確定究竟應該例項化哪一個具體產品類。

模式結構

工廠方法模式包含如下角色:

  • Product:抽象產品
  • ConcreteProduct:具體產品
  • Factory:抽象工廠
  • ConcreteFactory:具體工廠
    在這裡插入圖片描述
    如上圖,建立一個具體產品物件時,需要呼叫ConcreteFactory物件。ConcreteFactory物件是工廠類Factory的實現類,且該類實現Product建立依賴於ConcreteProduct類,而ConcreteProduct類又是抽象類Product的實現類。

時序圖(時序圖理解不透徹,可能有錯誤)

在這裡插入圖片描述
main方法呼叫工廠方法factoryMethod(),返回Product類(這是個同步訊息)。factoryMethod()方法的實現需要呼叫ConcreteFactory類,然後執行create方法(這是一個非同步訊息),create()方法需要呼叫ConcreteProduct類,建立了Product類。隨後Product類可以呼叫use()方法。

程式碼分析

//抽象產品類
abstract class Product {
    public Product(){
    }
}
//具體產品
public class ProductCar extends Product {
    public ProductCar (){
        System.out.println("建造了一輛汽車");
    }
}
public class ProductBike extends Product{
    public ProductBike(){
        System.out.println("建造了一輛自行車");
    }
}

//抽象工廠類
abstract class Factory {
    public Product createProduct() {
        return null;
    }
}

//具體工廠類
public class CarFactory extends Factory {
    @Override
    public Product createProduct() {
        return new ProductBike();
    }
}

public class BikeFactory extends Factory{
    @Override
    public Product createProduct() {
        return new ProductBike();
    }
}

模式分析

工廠模式方法是簡單工廠模式的進一步推廣,由於使用了物件導向的多型性,工廠方法模式保留了簡單工廠模式的優點,同時通過實現抽象工廠類,克服了簡單工廠方法工廠類擔責過重牽一髮動全身的情況,使得模式更符合開閉原則。

工廠方法模式的優缺點

優點

繼承了簡單工廠方法的優點,例如:

  • 使用者只需要關心所需要的建立物件的工廠方法即可。無需關心建立細節
    同時:
  • 使用了物件導向的多型性,具體工廠類擁有共同的抽象工廠類,具體產品類擁有共同的抽象產品類,使得工廠能夠靈活的確定建立何種產品物件。
  • 新增產品時,無需修改既有的工廠類產品類,只需要新增一個相應的具體工廠類與具體產品類即可。

缺點

  • 新增產品時,需要額外編寫具體工廠類,具體工廠類與具體產品類成對增加,增加了系統的複雜性。
  • 由於考慮到系統的可擴充套件性,需要引入抽象層,在客戶端程式碼中均使用抽象層進行定義,增加了系統的抽象性和理解難度,且在實現時可能需要用到DOM、反射等技術,增加了系統的實現難度。

適用情況

在以下情況下可以使用工廠方法模式:

  • 一個類不知道它所需要的物件的類客戶端需要知道建立具體產品的工廠類。
  • 一個類通過其子類來指定建立哪個物件:在工廠方法模式中,對於抽象工廠類只需要提供一個建立產品的介面,而由其子類來確定具體要建立的物件,利用物件導向的多型性和里氏代換原則,在程式執行時,子類物件將覆蓋父類物件,從而使得系統更容易擴充套件。
  • 將建立物件的任務委託給多個工廠子類中的某一個,客戶端在使用時可以無須關心是哪一個工廠子類建立產品子類,需要時再動態指定,可將具體工廠類的類名儲存在配置檔案或資料庫中。

模式擴充套件

  • 使用多個工廠方法:可定義多個抽象工廠,具體工廠可以根據需要不同的抽象工廠類
  • 產品物件的重複使用:工廠物件可以將已建立的產品儲存起來,實現對存在的產品反覆使用。
  • 多型性的喪失和模式的退化:如果只有一個具體工廠,抽象工廠就可以省略,此時工廠方法發生退化。當只有一個具體工廠,在具體工廠中可以建立所有的產品物件,並且工廠方法設計為靜態方法時,工廠方法模式就退化成簡單工廠模式。

總結

參考部落格

  • 工廠方法模式又稱為工廠模式,它屬於類建立型模式。在工廠方法模式中,工廠父類負責定義建立產品物件的公共介面,而工廠子類則負責生成具體的產品物件,這樣做的目的是將產品類的例項化操作延遲到工廠子類中完成,即通過工廠子類來確定究竟應該例項化哪一個具體產品類。

  • 工廠方法模式包含四個角色:抽象產品是定義產品的介面,是工廠方法模式所建立物件的超型別,即產品物件的共同父類或介面;具體產品實現了抽象產品介面,某種型別的具體產品由專門的具體工廠建立,它們之間往往一一對應;抽象工廠中宣告瞭工廠方法,用於返回一個產品,它是工廠方法模式的核心,任何在模式中建立物件的工廠類都必須實現該介面;具體工廠是抽象工廠類的子類,實現了抽象工廠中定義的工廠方法,並可由客戶呼叫,返回一個具體產品類的例項。

  • 工廠方法模式是簡單工廠模式的進一步抽象和推廣。由於使用了物件導向的多型性,工廠方法模式保持了簡單工廠模式的優點,而且克服了它的缺點

  • 在工廠方法模式中,核心的工廠類不再負責所有產品的建立,而是將具體建立工作交給子類去做。這個核心類僅僅負責給出具體工廠必須實現的介面,而不負責產品類被例項化這種細節,這使得工廠方法模式可以允許系統在不修改工廠角色的情況下引進新產品。

  • 工廠方法模式的主要優點是增加新的產品類時無須修改現有系統,並封裝了產品物件的建立細節,系統具有良好的靈活性和可擴充套件性;其缺點在於增加新產品的同時需要增加新的工廠,導致系統類的個數成對增加,在一定程度上增加了系統的複雜性。

  • 工廠方法模式適用情況包括:一個類不知道它所需要的物件的類;一個類通過其子類來指定建立哪個物件;將建立物件的任務委託給多個工廠子類中的某一個,客戶端在使用時可以無須關心是哪一個工廠子類建立產品子類,需要時再動態指定。

相關文章