工廠三兄弟之工廠方法模式(二)

2021-08-09 06:23:30 字數 1879 閱讀 5435

2 工廠方法模式概述

在簡單工廠模式中只提供乙個工廠類,該工廠類處於對產品類進行例項化的中心位置,它需要知道每乙個產品物件的建立細節,並決定何時例項化哪乙個產品類。簡單工廠模式最大的缺點是當有新產品要加入到系統中時,必須修改工廠類,需要在其中加入必要的業務邏輯,這違背了「開閉原則」。此外,在簡單工廠模式中,所有的產品都由同乙個工廠建立,工廠類職責較重,業務邏輯較為複雜,具體產品與工廠類之間的耦合度高,嚴重影響了系統的靈活性和擴充套件性,而工廠方法模式則可以很好地解決這一問題。

在工廠方法模式中,我們不再提供乙個統一的工廠類來建立所有的產品物件,而是針對不同的產品提供不同的工廠,系統提供乙個與產品等級結構對應的工廠等級結構

。工廠方法模式定義如下:

工廠方法模式(factory method pattern):定義乙個用於建立物件的介面,讓子類決定將哪乙個類例項化。工廠方法模式讓乙個類的例項化延遲到其子類。工廠方法模式又簡稱為工廠模式(factory pattern),又可稱作虛擬構造器模式(virtual constructor pattern)或多型工廠模式(polymorphic factory pattern)。工廠方法模式是一種類建立型模式。

工廠方法模式提供乙個抽象工廠介面來宣告抽象工廠方法,而由其子類來具體實現工廠方法,建立具體的產品物件。工廠方法模式結構如圖2所示:

圖2 工廠方法模式結構圖

在工廠方法模式結構圖中包含如下幾個角色:

●product(抽象產品):

它是定義產品的介面,是工廠方法模式所建立物件的超型別,也就是產品物件的公共父類。

●concreteproduct(具體產品):

它實現了抽象產品介面,某種型別的具體產品由專門的具體工廠建立,具體工廠和具體產品之間一一對應。

●factory(抽象工廠):

在抽象工廠類中,宣告了工廠方法(factory method),用於返回乙個產品。抽象工廠是工廠方法模式的核心,所有建立物件的工廠類都必須實現該介面。

●concretefactory(具體工廠):

它是抽象工廠類的子類,實現了抽象工廠中定義的工廠方法,並可由客戶端呼叫,返回乙個具體產品類的例項。

與簡單工廠模式相比,工廠方法模式最重要的區別是引入了抽象工廠角色,抽象工廠可以是介面,也可以是抽象類或者具體類,其典型**如下所示:

inte***ce factory
在抽象工廠中宣告了工廠方法但並未實現工廠方法,具體產品物件的建立由其子類負責,客戶端針對抽象工廠程式設計,可在執行時再指定具體工廠類,具體工廠類實現了工廠方法,不同的具體工廠可以建立不同的具體產品,其典型**如下所示:

class concretefactory implements factory   

}

在實際使用時,具體工廠類在實現工廠方法時除了建立具體產品物件之外,還可以負責產品物件的初始化工作以及一些資源和環境配置工作,例如連線資料庫、建立檔案等。

在客戶端**中,只需關心工廠類即可,不同的具體工廠可以建立不同的產品,典型的客戶端類**片段如下所示:

……  

factory factory;

factory = new concretefactory(); //可通過配置檔案實現

product product;

product = factory.factorymethod();

……

可以通過配置檔案來儲存具體工廠類concretefactory的類名,更換新的具體工廠時無須修改源**,系統擴充套件更為方便。

思考工廠方法模式中的工廠方法能否為靜態方法?為什麼?

工廠三兄弟之工廠方法模式(四)

sunny公司開發人員通過進一步分析,發現可以通過多種方式來初始化日誌記錄器,例如可以為各種日誌記錄器提供預設實現 還可以為資料庫日誌記錄器提供資料庫連線字串,為檔案日誌記錄器提供檔案路徑 也可以將引數封裝在乙個object型別的物件中,通過object物件將配置引數傳入工廠類。此時,可以提供一組過...

工廠三兄弟之工廠方法模式(一)

簡單工廠模式雖然簡單,但存在乙個很嚴重的問題。當系統中需要引入新產品時,由於靜態工廠方法通過所傳入引數的不同來建立不同的產品,這必定要修改工廠類的源 將違背 開閉原則 如何實現增加新產品而不影響已有 工廠方法模式應運而生,本文將介紹第二種工廠模式 工廠方法模式。1 日誌記錄器的設計 sunny軟體公...

工廠三兄弟之工廠方法模式(四)

sunny公司開發人員通過進一步分析,發現可以通過多種方式來初始化日誌記錄器,例如可以為各種日誌記錄器提供預設實現 還可以為資料庫日誌記錄器提供資料庫連線字串,為檔案日誌記錄器提供檔案路徑 也可以將引數封裝在乙個object型別的物件中,通過object物件將配置引數傳入工廠類。此時,可以提供一組過...