設計模式(二) 工廠模式

2021-09-12 05:44:36 字數 4010 閱讀 4577

前言

我在面試的時候,有時候會問到候選人有沒有熟悉的設計模式,一般大部分候選人會選擇說熟悉單例和工廠(也有部分人會說熟悉觀察者),如果我進一步問候選人是如何應用工廠模式的,10個候選人有10個會舉連線sqlserver,oracle,mysql等不同資料庫時會用工廠模式產生不同的連線的例子。

omg,我知道大家都是愛學習的同學,但是大家為什麼不仔細想想,網上一搜一大堆的例子,你能看到,別人難道看不到?我不知道大家能不能感受,作為乙個面試官,問到乙個問題的時候,所有候選人都用同乙個例子來回答你的感受。。。

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

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

簡單工廠

int prodno;

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

public iproduct getproduct()

} }

//產品a

class producta: iproduct

//產品b

class productb : iproduct

//產品介面

inte***ce iproduct

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

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

2.工廠模式

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

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

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

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

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

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

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

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

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

到底何時應該用工廠模式

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

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

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

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

二 設計模式 工廠模式

一.傳統時以pizza類舉例,乙個抽象類pizza,由幾個pizza實現類實現,主餐廳看看客戶點什麼便生產,但是如果需要增加新的pizza品種,則要增加乙個新的實現類,然後主餐廳裡增加對邏輯的判斷,顯然,違背了開放關閉原則。所以 工廠模式為解決某些需要生產大量一批類的問題 二.簡單工廠模式 定義了乙...

設計模式(二)工廠模式

與 模式不同,生產模式隱藏過程,只關注結果 簡單工廠,工廠方法,抽象工廠 一,簡單工廠模式 public inte ce car public class aodi implements car public class baoma implements car public class facto...

設計模式 (二)工廠模式

昨天看了一下工廠模式,發現大部分概念都太官方,不想看,所以我今天自己用 來擼了一遍,如果有不對的地方,歡迎博友討論。請註明出處!文字不多,主要通過 來理解,概念請結合 去網上搜 場景 某汽車公司老闆讓你設計乙個汽車介面,介面用來開車駕駛,例如汽車有寶馬 奧迪 賓士.首先抽象出car類 public ...