工廠模式(二)

2021-09-19 04:03:45 字數 3924 閱讀 5080

工廠模式中,簡單工廠,工廠和抽象工廠的區別,以及每種工廠的優劣勢時,候選人基本都會矇圈。如果自己沒有使用過,甚至使用過沒有認真思考過,肯定是回答不上來的。好吧,下面我就來跟大家講講工廠模式。

工廠模式,實際上也會根據業務情景不同會有不同的實現方式。一般分為3種。簡單工廠,工廠和抽象工廠。顧名思義,這三種從簡單到抽象,名稱越來越高大上,實現方式肯定是越來越複雜,所以,我們可以得到第乙個結論,三種工廠的實現是越來越複雜的。

先來看看簡單工廠。廢話不多,擼**:

//產品a

class producta: iproduct

//產品b

class productb : iproduct

//產品介面

inte***ce iproduct

int prodno;

public ******factory(int prodno) //構造工廠時告知工廠產品標識

public iproduct getproduct()

}}

注意,這段例子**當然還可以寫的簡單點,我完全可以在簡單工廠中直接返回字串而避免寫產品類和產品介面。但是即便是真實的業務場景是這樣(真的只需要返回字串或者數字什麼的),大家還是把產品類和工廠類分開,這樣才是使用工廠模式的初衷,也就是實現解耦。

那麼大家看看這段簡單工廠的例子,如果我現在問,這個會有什麼問題,該如何回答呢?提示一下,如果說來了乙個需求,增加乙個產品c,該如何辦?沒錯,簡單工廠的問題就在於swich case(或者if else)。每當新增一種產品時,你都需要去維護工廠中的判斷語句,造成的後果就是可能這個工廠類會非常非常長,各種判斷全部擠在一起,給擴充套件和維護帶來很多麻煩。說白了,你的產品和工廠還是沒有完全解耦,繫結在一起的。所以,我們得到了第二個結論:簡單工廠通過構造時傳入的標識來生產產品,不同產品都在同乙個工廠中生產,這種判斷會隨著產品的增加而增加,給擴充套件和維護帶來麻煩。那麼,如何解決這個問題呢?

你猜對了,工廠模式可以解決這個問題,**擼上:

inte***ce ifactory //工廠介面

//a工廠類

public class factorya: ifactory

public iproduct getproduct() //a工廠生產a產品

}//b工廠類

public class factoryb : ifactory

public iproduct getproduct() //b工廠生產b產品

}//產品介面

public inte***ce iproduct

//產品a

public class producta : iproduct

//產品b

public class productb : iproduct

仔細觀察這段**,在工廠模式中,已經將工廠類分開,不再將所有產品在同一工廠中生產,這樣就解決了簡單工廠中不停的switch case的問題。如果說來了乙個c產品,那麼我們只需要寫乙個c工廠和c產品,在呼叫時用c工廠生產c產品即可,a和b工廠和產品完全不受影響。ok,優化說完了,但是還是有問題。

問題在**呢?當業務需求是需要生產產品族的時候,工廠就不再適合了。首先我們搞清楚何謂產品族和產品等級結構。舉個例子來說,比如三星是乙個品牌,三星生產洗衣機,電視,冰箱;格力也是乙個品牌,格力也生產洗衣機,電視,冰箱。那麼,三星工廠和格力工廠生產的2個品牌的洗衣機,就在洗衣機這種產品的產品等級結構中(當然洗衣機產品等級結構中還有lg,海爾,三菱等等不同的品牌的工廠的產品),所以,洗衣機就是乙個產品等級。那麼三星生產的三星洗衣機,三星電視機,三星冰箱就是三星這個工廠的產品族。可能還會有西門子工廠產品族,格力工廠產品族,美的工廠產品族等等。

好了,搞清楚了產品等級結構和產品族,我們得到第三個結論:工廠模式無法解決產品族和產品等級結構的問題。再回過頭來看抽象工廠模式。如果如上所述,業務場景是需要實現不同的產品族,並且實現產品等級結構,就要用到抽象工廠模式了。還是來看**:

//工廠介面,即抽象工廠

inte***ce ifactory

//三星的工廠,生產三星的產品族

public class samsungfactory : ifactory

public ifridge createfridge()

}//格力的工廠,生產格力的產品族

public class greefactry : ifactory

public ifridge createfridge()

}//冰箱產品介面

public inte***ce ifridge

//空調介面

public inte***ce iaircondition

//三星的冰箱

public class samsungfridge: ifridge

//格力的冰箱

public class greefridge : ifridge

//三星的空調

public class samsungaircondition : iaircondition

//格力的空調

public class greeaircondition : iaircondition

我們可以看到,在工廠模式中,乙個工廠生產乙個產品,所有的具體產品是由同乙個抽象產品派生的,不存在產品等級結構和產品族的概念;而在抽象工廠中,同乙個等級的產品是派生於乙個抽象產品(即產品介面),乙個抽象工廠派生不同的具體工廠,每個具體工廠生產自己的產品族(包含不同產品等級)。所以我們得到第四個結論,工廠模式中,乙個工廠生產乙個產品,所有產品派生於同乙個抽象產品(或產品介面);而抽象工廠模式中,乙個工廠生產多個產品,它們是乙個產品族,不同的產品族的產品派生於不同的抽象產品(或產品介面)。

好了我們歸納一下,工廠模式實際上包含了3中設計模式,簡單工廠,工廠和抽象工廠,關鍵點如下:

一、三種工廠的實現是越來越複雜的

二、簡單工廠通過構造時傳入的標識來生產產品,不同產品都在同乙個工廠中生產,這種判斷會隨著產品的增加而增加,給擴充套件和維護帶來麻煩

三、工廠模式無法解決產品族和產品等級結構的問題

四、抽象工廠模式中,乙個工廠生產多個產品,它們是乙個產品族,不同的產品族的產品派生於不同的抽象產品(或產品介面)。

好了,如果你能理解上面的關鍵點,說明你對工廠模式已經理解的很好了,基本上面試官問你工廠模式,你可以昂頭挺胸的說一番。但是,面試官怎麼可能會放過每一次虐人的機會?你仍然可能面臨下面的問題:

在上面的**中,都使用了介面來表達抽象工廠或者抽象產品,那麼可以用抽象類嗎?有何區別?

從功能上說,完全可以,甚至可以用介面來定義行為,用抽象類來抽象屬性。抽象類更加偏向於屬性的抽象,而用介面更加偏向行為的規範與統一。使用介面有更好的可擴充套件性和可維護性,更加靈活實現鬆散耦合,所以程式設計原則中有一條是針對介面程式設計而不是針對類程式設計。

到底何時應該用工廠模式

根據具體業務需求。不要認為簡單工廠是用switch case就覺得一無是處,也不要覺得抽象工廠比較高大上就到處套。我們使用設計模式是為了解決問題而不是炫技,所以根據三種工廠模式的特質,以及對未來擴充套件的預期,來確定使用哪種工廠模式。

3.說說你在專案中工廠模式的應用

如果你看了這篇文章,被問到這個問題時,還傻乎乎的去舉資料庫連線的例子,是要被打板子的。。。比如我之前做過乙個旅遊產品的b2b**,根據不同型別的業務形態,產品也是不同的,有國內跟團,出境跟團,國內自由行,出境自由行,郵輪五種產品,並且後面可能還會有門票,酒店,機票等等產品,其中有些聯絡也有些區別。

所以在面試中,我完全把工廠模式和我做的東西聯絡起來,如何建立工廠,如何生產不同的產品,如何擴充套件,如何維護等等。我想,把理論應用到實際,而且是真實業務邏輯中,給面試官的印象無論如何不會太差,甚至會對你刮目相看。

當然,即便是你沒有真的使用過,如果面試官問道了工廠模式,你仍然可以把你以往的經驗和設計模式聯絡起來回(hu)答(you)面試官,只要你理解了,把來龍去脈說清楚,並且可以回答問題,我想應該是可以令面試官滿意的。

工廠模式二 工廠方法模式

使用者只需要關心產品對應的工廠,不需要關心建立細節。例如貓和狗都屬於動物一類,都具有吃飯這個功能。先定義介面ianimal public inte ce ianimal實現介面ianimal介面cat類和dog類 public class cat implements ianimal public ...

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

我們在學習乙個東西之前,應該要先了解下他為什麼出現,他解決了什麼問題。這樣才可以帶著思考的高效學習。以資料庫為例,我們知道常見的關係型資料庫有mysql sqlserver oracle等,每種資料庫連線例項的建立都是複雜且易錯麻煩的。如果將這些連線例項交給使用者來建立,是十分不合適的。我們就希望有...

工廠模式之二 工廠模式 彌補簡單工廠模式弊端

首先回顧下簡單工廠模式的主要內容 簡單工廠模式就是實質就是專門定義了乙個工廠類,利用工廠類的靜態方法來根據使用者需求建立物件,優點是客戶端的壓力較小,客戶端不需要做建立例項的操作,只需要呼叫工廠類中的方法就可以獲得對應例項,而其缺點也非常明顯,其所有建立工作都在乙個工廠類完成,耦合性較高,而且當系統...