一起學設計模式 02 工廠模式

2021-09-19 13:36:33 字數 3649 閱讀 9389

如果你還沒了解六大軟體設計原則的話,建議先谷歌下,再來學習設計模式。這對理解設計模式和記憶設計模式的經典寫法都會有很大幫助。學習設計模式,光是記寫法沒有意義,要學習的是設計思想,為什麼要這麼做,這麼做的好處是什麼。懷著這兩個問題來學習設計模式,你會發現六大軟體設計原則在設計模式中的應用,相應的也會加強你對六大軟體設計原則的記憶。

很多人,包括我自己在看工廠模式的時候都會問乙個問題,工廠模式的好處到底是什麼?有人說抽象?我覺得那是依賴倒置的好處,工廠模式遵循了依賴倒置原則,自然有抽象的特點,但這並不是根本好處,但凡遵循這一原則的都會具備這個特點。所以在我們在學習某個知識點的時候,要多看幾篇文章,反覆對比斟酌,不要希望說「***看這一篇就夠了」(很多部落格的標題都會這麼起),包括這篇文章,也僅僅是作為讀者的乙個參考。那麼工廠模式的好處到底是啥,我個人認為工廠模式最根本的好處是:

工廠模式最直接的好處就是遮蔽了物件的建立細節,將使用者和物件的建立過程隔離開來。特別是對那些建立過程非常複雜的物件,使用者不再需要關心這些物件是如何建立的,這麼做簡化了使用者的操作,降低了呼叫難度。另外,由於建立的過程被工廠封裝,也避免了建立物件的**,散落在各個模組的情況,同時也減少了**開發工作量。當然工廠模式也具備多型的特性,這是因為工廠模式遵循依賴倒置原則,只是乙個附帶的特性。最後,多了這層封裝也為例項建立的集中管理提供了便捷。

假如我需要乙個thinkpad 的computer電腦例項來辦公,這個thinkpad電腦例項是由a screen顯示屏,b keyboard鍵盤,c cpu 處理器, d ram記憶體條構成,且有乙個非常複雜的組裝過程。好了,作為乙個使用者,我可能需要這麼寫:

screen ascreen = new ascreen(a);

keyboard bkeyborad = new bkeyboard(b);

cpu ccpu = new ccpu(c);

ram dram = new dram(d);

computer computer = new thinkpad(ascreen, bkeyborad, ccpu, dram);

我作為電腦的使用者,我並不關心電腦是由哪些部分構成的,是怎麼組裝的。這些內容對使用者來說,顯然是多餘的。而且假如我在多處需要使用這個thinkpad的例項,這段構造thinkpad的**會出現在多個地方。某天thinkpad的構成變了,使用的是fram,那我還要把散落在各個模組的構造**挑出來,把引數dram改為fram。

有的人可能會說,那我提供乙個無參建構函式,把建立物件的細節都放裡面,這樣不也可以避免當入參發生變化時,不需要到處修改**,而且也遮蔽了建立細節。這樣確實是可以,但是實際上有多少個類的是可以無參構造的呢,這種情況就非常極端了。設計模式只是乙個解決實際問題的參考,有沒有用要不要用都是結合實際情況決定,當然因為其廣泛的適用性,所以被總結為乙個模式,類構成非常簡單且產品單一,當然可以不用工廠模式,沒必要鑽牛角尖。

下面我們從簡單工廠模式開始,一步步深入的學習簡單工廠模式,工廠方法模式,抽象工廠模式,看看工廠模式是怎麼樣一步步演變的。

簡單工廠模式通常由三部分構成,經典寫法就是switch語句來決定返回的物件。

//抽象介面

public inte***ce computer

//具象類

public class mac implements computer

}public class thinkpad implements computer

}//簡單工廠-告訴工廠想要什麼型別的電腦,工廠就給你什麼型別的電腦,**電腦需要修改工廠類增加case分支

public class ******factory

}}//客戶端**

public class testcomputer

}

在產品不多的情況下,我們可以接受使用簡單工廠模式。但是在產品型別比較多的時候,簡單工廠模式就不再適用。想象下,每增加乙個產品,我們都需要修改簡單工廠(違背開閉原則),而且我們不停的往這個簡單工廠裡面新增**,越來越多,非常臃腫,可讀性和可維護性會變差。而且,我們需要不停的修改簡單工廠的**,違背了開閉原則(只擴充套件不修改原**)。這個時候,工廠方法模式就來了。

注1:順便提一下使用反射來建立例項可以實現不違反開閉原則的簡單工廠

public static computer createcomputerbyreflect(string type) 

throws illegalacces***ception,

instantiationexception,

classnotfoundexception

//客戶端**

public class testcomputer

}

注2:簡單工廠模式又稱靜態工廠模式,使用靜態方法,無需例項化簡單工廠。至於工廠方法模式和抽象工廠模式為啥就不用靜態方法,個人理解是因為這兩個模式對工廠進行了抽象(定了工廠介面),如果用了靜態方法,這些方法無法被重寫。

工廠方法模式,可以理解為簡單工廠模式的加強版,對具象的工廠類做了一層抽象(構成多了一層工廠介面),不同產品的建立不再集中在乙個工廠內,而是由各自專門的工廠類負責。新增乙個產品,無需改動原有工廠類,只需要新增乙個新的工廠類即可,在繼承了簡單工廠模式的優點之餘,也克服了簡單工廠模式違背開閉原則的問題。當然缺點就是類變多了,開發量增加了。

//抽象的產品介面

public inte***ce computer

//具象的產品類

public class mac implements computer

}public class thinkpad implements computer

}//抽象的工廠介面

public inte***ce abmethodfactory

//具象的工廠類

public class macfactory implements abmethodfactory

}//具象的工廠類

public class thinkpadfactory implements abmethodfactory

}//客戶端**

public class testcomputer

}

前面兩種工廠,生產的都是單一產品。實際上,有的時候我們會有生成一系列產品的需求,比如我要生產的是乙個電腦套裝(乙個產品系列),包含電腦,滑鼠,鍵盤。當我們面臨多個產品組合協作的場景時,使用抽象工廠,我們可以保證客戶端使用的產品,都是如我們所希望的出自同一系列(比如 mac電腦要接type-c介面的滑鼠),我只要切換工廠,就能實現配套措施的全部切換,改變整個系統的行為。缺點是如果我要在產品族裡面再加乙個產品,那麼我需要修改工廠介面,增加乙個獲取新產品的方法抽象方法定義,所有具象工廠也要增加對應實現,違背了開閉原則。

抽象工廠的構成和工廠方法模式一致,但是其工廠內會提供多個方法用於獲取同乙個系列的不同產品。

**只貼工廠介面和其中乙個工廠吧,不然篇幅太冗長了。

public inte***ce abmethodfactory 

public class macfactory implements abmethodfactory

@override

public mouse createmouse()

}

一起學設計模式 組合模式

組合模式 composite pattern 屬於結構型模式的一種,組合多個物件形成樹形結構來表示部分 整體的結構層次,對單個物件 葉子物件 和組合物件 容器物件 的使用具有一致性 組合模式對單個物件 葉子物件 和組合物件 容器物件 具有一致性,它將物件組織到樹結構中,可以用來描述整體與部分的關係。...

一起學設計模式 外觀模式

外觀模式 facade pattern 屬於結構型模式的一種,為子系統中的一組介面提供乙個統一的入口,它通過引入乙個外觀角色來簡化客戶端與子系統之間的互動.外觀模式是一種使用頻率非常高的結構型設計模式,當你要為乙個複雜子系統提供乙個簡單介面時。子系統往往因為不斷演化而變得越來越複雜。大多數模式使用時...

一起來學設計模式(2) 簡單工廠模式

其實,在gof的23種設計模式中,並沒有簡單工廠模式這種說法,為了和工廠模式 抽象工廠模式逐一對比,我們還是先從簡單工廠模式說起。工廠 即用來生產 產品 考慮以下需求 我需要通過乙個類來建立乙個蘋果,或者是建立乙個梨,或者是建立乙個。在上邊的需求中,這個可以建立蘋果 梨 香蕉的類即為簡單工廠類。同時...