設計模式 並不簡單的工廠模式

2022-03-20 04:34:20 字數 3473 閱讀 2439

一般情況下,工廠模式分為三種更加細分的型別:簡單工廠、工廠方法和抽象工廠。實際上,這三種我們最常用得是第一種簡單工廠和工廠方法模式。而抽象工廠的原理稍微複雜點,在實際的專案中相對也不常用。所以,我們今天主要講解的重點是前兩種工廠模式。

// 建立抽象產品類,定義具體產品得公共介面

abstract class product

// 建立具體產品類(繼承抽象產品類),定義生產的具體產品

//具體產品類a

class producta extends product

}//具體產品類b

class productb extends product

}

// 建立工廠類,通過建立靜態方法從而根據傳入不同引數建立不同具體產品類的例項

class factory

}}

可以看到,對於上面得簡單工廠的實現方法,如果我們要新增新的product,那勢必要改動到 factory 的**,那這是不是違反開閉原則呢?實際上,如果不是需要頻繁地新增新的 product,只是偶爾修改一下factory**,稍微不符合開閉原則,也是完全可以接受的。

除此之外,在 factory 有一組 if 分支判斷邏輯,是不是應該用多型或其他設計模式來替代呢?實際上,如果 if 分支並不是很多,**中有 if 分支也是完全可以接受的。應用多型或設計模式來替代 if 分支判斷邏輯,也並不是沒有任何缺點的,它雖然提高了**的擴充套件性,更加符合開閉原則,但也增加了類的個數,犧牲了**的可讀性。

總結一下,儘管簡單工廠模式的**實現中,有多處 if 分支判斷邏輯,違背開閉原則,但權衡擴充套件性和可讀性,這樣的**實現在大多數情況下(比如,不需要頻繁地新增 product,也沒有太多的 product)是沒有問題的。

//建立抽象工廠類,定義具體工廠的公共介面

abstract class ifactory

//工廠a類 - 生產a類產品

class factorya extends ifactory

}//工廠b類 - 生產b類產品

class factoryb extends ifactory

}

實際上,這就是工廠方法模式的典型**實現。這樣當我們新增一種 product 的時候,只需要新增乙個實現了 ifactory 介面的 factory 類即可。所以,工廠方法模式比起簡單工廠模式更加符合開閉原則。

看似很完美了,但是這裡還是有一些小問題,簡單工廠只是把麻煩的if判斷從工廠類,移交到了使用者手裡,怎麼說呢?來看下面這段**

//生產工作流程

public class factorypattern

public ifactory load(string factorytype) else if ("b".equalsignorecase(factorytype)) else

return factory;

}}

從上面的**實現來看,工廠類物件的建立邏輯又耦合進了 load() 函式中,跟我們最初的**版本非常相似。假如我們的業務需求是,根據讀取的配置檔案來建立相應的product,其實不管是簡單工廠模式還是方法工廠模式,上訴的if判斷都無法消滅掉(所以在 gof 的《設計模式》一書中,它將簡單工廠模式看作是工廠方法模式的一種特例

講完了簡單工廠、工廠方法,我們再來看抽象工廠模式。抽象工廠模式的應用場景比較特殊,沒有前兩種常用,不是我們學習的重點,我們來簡單了解一下就行了。

我們這裡有乙個需求場景,有乙個工廠,他主要生產容器和模具。對於容器和模具下面又分很多種類。如下:

// 容器

containerproducta

containerproductb

//模具

mouldproducta

mouldproductb

針對這種特殊的場景,如果還是繼續用工廠方法來實現的話,我們要針對每個產品 都編寫乙個工廠類,也就是要編寫 4 個工廠類。如果我們未來還需要增加了其他型別的生產產品(比如 杯子),那就要再對應地增加 2 個工廠類。而我們知道,過多的類也會讓系統難維護。這個問題該怎麼解決呢?

抽象工廠就是針對這種非常特殊的場景而誕生的。我們可以讓乙個工廠負責建立多個不同型別的物件(容器、模具、杯子 等),而不是只建立一種 product 物件。這樣就可以有效地減少工廠類的個數。具體的**實現如下所示:

//建立抽象工廠類,定義具體工廠的公共介面

abstract class factory

//建立抽象產品族類 ,定義具體產品的公共介面;

abstract class abstractproduct

//容器產品抽象類

abstract class containerproduct extends abstractproduct

//模具產品抽象類

abstract class mouldproduct extends abstractproduct

//容器產品a類

class containerproducta extends containerproduct

}//容器產品b類

class containerproductb extends containerproduct

}//模具產品a類

class mouldproducta extends mouldproduct

}//模具產品b類

class mouldproductb extends mouldproduct

}

//a廠 - 生產模具+容器產品

class factorya extends factory

@override

public product manufacturemould()

}//b廠 - 生產模具+容器產品

class factoryb extends factory

@override

public product manufacturemould()

}

我們來一塊總結回顧一下,這裡的三種工廠模式中,簡單工廠和工廠方法比較常用,抽象工廠的應用場景比較特殊,所以很少用到,其實了解一下就可以了。

當建立邏輯比較複雜,是乙個「大工程」的時候,我們就考慮使用工廠模式,封裝物件的建立過程,將物件的建立和使用相分離。何為建立邏輯比較複雜呢?

對於第一種情況,當每個物件的建立邏輯都比較簡單的時候,推薦使用簡單工廠模式,將多個物件的建立邏輯放到乙個工廠類中。

當每個物件的建立邏輯都比較複雜的時候,為了避免設計乙個過於龐大的簡單工廠類,推薦使用工廠方法模式,將建立邏輯拆分得更細,每個物件的建立邏輯獨立到各自的工廠類中。

還是那句話,不要為了使用設計模式而用設計模式,設計模式都是在相應的使用場景下而誕生的。

設計模式 工廠模式(簡單工廠)

一 簡單工廠 定義 簡單工廠模式 factory pattern 屬於類的創新型模式,又叫靜態工廠方法模式 static factorymethod pattern 是通過專門定義乙個類來負責建立其他類的例項,被建立的例項通常都具有共同的父類。特點 工廠類直接實現,乙個產品介面,乙個工廠類可以產生多...

設計模式(簡單工廠模式 工廠模式 抽象工廠模式)

當邏輯較為簡單時,可以直接建立對應的類。如下 include using namespace std class class banana class pear intmain 通過此 可以發現,使用者直接與客戶接觸,違背了dip 依賴倒轉 原則,過於麻煩,所以引出簡單工廠模式。include us...

設計模式 簡單工廠設計模式

請用任意一種物件導向語言實現計算器控制台程式,要求輸入兩個數和運算符號,得到結果。operation運算類 public class operation set public double numberb set public virtual double getresult 加減乘除類 using...