天天看點

《設計模式》學習筆記2——簡單工廠模式

簡單工廠模式并不屬于GoF(Gang of Four四人組)23中設計模式,有些地方的解釋說因為簡單工廠模式太簡單,是以23中設計模式就沒有單獨列出。

但是簡單工廠模式在實際的應用中卻很常用,是以在劉偉老師的《設計模式》一書中就還是列了出來。

簡單工廠模式引用書中的定義如下:

簡單工廠模式(Simple Factory Pattern):定義一個工廠類,它可以根據參數的不同傳回不同類的執行個體,被建立的執行個體通常都具有共同的父類。因為在簡單工廠模式中用于建立執行個體的方法是靜态(static)方法,是以簡單工廠模式又被稱為靜态工廠方法(Static Factory Method)模式,它屬于類建立型模式

對于這個模式,我覺得說靜态工廠模式比說簡單工廠模式更能讓人記住。靜态工廠模式,通過靜态兩個字就可以知道需要有一個靜态的工廠方法,然後隻要再了解一下何謂工廠,基本上就記住了這個模式。

那麼何謂工廠呢,衆所周知,生産産品的地方就是工廠。

對于工廠而言,需要有能正常運作的生産線,這個生産線可能是全自動化的,也可能是人工操作的,除此之外,還需要有被生産的産品。

根據上邊的思路,我們便可以轉換為代碼,首先寫出我們的産品類:

有了這樣一個産品類,便可以建立該類的具體産品執行個體,學習java的必然知道最基本的建立對象執行個體的方式就是使用new關鍵字,比如<code>new MyProduct()</code>。就像下邊的代碼:

這種方式其實相當于現實生活中某個人需要一個什麼東西,然後自己制造一個出來。

這種情況現實生活中必然是存在的,但是也必然有一定的限制,不可能每個人都能制造每種東西,是以還有很多東西個人制造不出來,或者說個人制造的成本太高,是以便有了專門制造某類東西的工廠,也就是我們的工廠類:

那麼這個時候,我們需要用某個東西的人,簡稱為消費者,就不需要自己再制造這類東西,也不需要如何制造這類東西,可以更加友善的使用:

這樣一來,我們需要的東西隻需要調用工廠的購買方法,或者說工廠提供給外邊的擷取産品的方法,然後就能擷取到想要的産品了。

然而,有一個很不愉快的問題出現了,上邊的代碼中,産品确實不需要自己建立,不需要自己new了,但是工廠卻是被我們new出來的。

這樣問題就大了,相當于我僅僅需要某個産品,然後為了這個産品,我必須自己建立了一個工廠,而且每個需要這個産品的人都要建立一個該産品的工廠,這顯然是不合理也不可能的。

我們需要的僅僅是這樣而已:

那麼工廠方法也就需要改成靜态的,使我們隻要用類名就可以調用擷取産品的方法:

好了,現在對于某個産品,工廠就合理的提供了一個給外邊擷取産品的方法,而外邊的消費者也能通過一聲<code>MySimpleFactory.getProduct()</code>的呼喚愉快的擷取到需要的産品了。

然而,如果後邊這個工廠擴大了,開始營運的産品不再單一了,例如牙膏,一開始隻是成年人用的牙膏,後邊又增加了兒童牙膏,那麼很顯然這時候我們工廠提供的擷取産品的無參方法就難以繼續擔當大任了。

因為隻通過一聲<code>我要買牙膏</code>的呼喚,工廠根本無法知道消費者需要的是哪種,是以我們的工廠方法需要有參數,并且根據不同的參數給予不同的産品:

現在,基本解決了上邊不知道消費者具體要什麼的問題,但是,工廠内部卻犯難了,因為根據原本産品制造說明說(産品類的定義),工廠能制造出來的産品隻有一種啊。

是以,原本的産品也需要更新,也就是本身的預設無參構造器不能滿足現有的需求了,我們可能需要增加有參數的構造方法,需要更新原本的産品制造說明書,并通過參數來确定具體的産品。

那麼以上的一些問題也暫時解決了,不管是需要兒童牙膏還是普通牙膏,工廠都能正确的提供,消費者也都能正确的擷取。

隻是,如果後邊工廠又擴大了,還要加入環保牙膏、特效美白牙膏呢?那麼我們就需要不斷的修改原本的産品構造方法,就如一本産品制造說明書要繼續加厚。

很顯然,這将導緻那個有參數的構造方法越來越臃腫,如果每種産品的制造方法都異常複雜的話,我們的一本産品制造說明書也将可能達到需要人擡的地步。

是以,這樣不是辦法,我們需要把各自具體産品的制造說明書分開,也就是我們的産品類需要由一個變成多個:

明眼人應該一眼就看出了上述代碼的問題,這兩個類幾乎一模一樣,唯獨不同的就是兒童牙膏增加了一個去鉛的方法。

很顯然,這樣的代碼是嚴重重複,不被看好的代碼,十足的浪費資源。是以我們需要把這些共同的東西給提取出來,形成一個父類,而這個父類不是具體的産品類,就需要聲明為抽象類,然後我們的産品類就應該是這樣了:

那麼工廠類中具體産品的選擇,就可以改成下邊這樣:

好了,一個比較标準的簡單工廠模式就出來了,由上邊的分析可以知道簡單工廠模式的幾個要點:

需要有一個生産産品的産品類(工廠)和靜态的輸出産品的方法,這個方法包含一些必要判斷邏輯;

需要有一個抽象的産品父類,定義産品的公共屬性和方法;

需要有具體的産品類;

隻要提供正确的參數,就能通過靜态工廠方法擷取到具體的産品。

通過上邊的一系列分析和執行個體,可以知道簡單工廠模式的一些優點,他可以使消費者不必關心具體産品的建立,隻需要一個參數就能得到需要的産品,實作了一定程度的松耦合。

同時,不同的産品不同的子類,也使得後續更容易拓展。

但是由于所有産品都通過工廠建立,不同産品擷取的邏輯判斷都在工廠方法中,是以具體的産品和工廠的耦合度就必然增大,同時在産品類的基礎上也額外的增加了工廠類。

是以,如果産品很多的話,這種簡單工廠模式便會變得臃腫而不易維護。