本博文僅僅是筆者自己的學(xué)習路線(xiàn),歸納整理了一些好的設計模式資料。
參考資料:c#設計模式-策略模式?c#設計模式之策略模式
定義是:封裝一組算法,每個(gè)算法為獨立的類(lèi),可以相互替代,因為它們有相似的行為。
策略模式主要是將產(chǎn)品共有的部分抽象出來(lái),不同的行為據此抽象作不同的具體實(shí)現,最后再有一個(gè)Context解耦客戶(hù)端調用與服務(wù)端的實(shí)現,客戶(hù)端是明確知道有哪些行為的。
注意: 如果優(yōu)化的話(huà),可以使用抽象類(lèi),將變化的算法設為抽象方法,或虛方法,這樣讓子類(lèi)對該方法進(jìn)行實(shí)現即可,同樣可以實(shí)現該需求,而且代碼重用性應該會(huì )更好
參考資料:C#設計模式(3)——工廠(chǎng)方法模式 ?C#設計模式(1)——簡(jiǎn)單工廠(chǎng)模式 ? C#設計模式(2)——工廠(chǎng)模式?工廠(chǎng)模式-C#改良實(shí)現
工廠(chǎng)模式主要是用來(lái)創(chuàng )建產(chǎn)品(即對象),在指定的工廠(chǎng)中構建指定的產(chǎn)品。整個(gè)的構建過(guò)程都是解耦的。
由簡(jiǎn)單工廠(chǎng)模式到工廠(chǎng)模式的演進(jìn),是設計模式的原則之一:開(kāi)放封閉原則 推進(jìn)的。這一點(diǎn)在我們日常開(kāi)發(fā)中有很明顯的體現,我個(gè)人也是"后知后覺(jué)"。代碼的開(kāi)發(fā)應該對擴展開(kāi)放,對修改封閉。
對比了下策略模式與工廠(chǎng)模式的實(shí)現,我發(fā)現其實(shí)可以很簡(jiǎn)單實(shí)現兩者的相互轉換:抽象和具體都是變動(dòng),策略模式中的Context層替換為工廠(chǎng)模式中的工廠(chǎng)層,就OK了。但是兩者的含義不一樣。從代碼來(lái)分析,策略模式是在客戶(hù)端已經(jīng)明確了產(chǎn)品,工廠(chǎng)模式則是將產(chǎn)品委托給了工廠(chǎng)來(lái)創(chuàng )建??蓞⒖? 簡(jiǎn)單工廠(chǎng)模式與策略模式的區別。
參考資料:C#設計模式-建造者模式?C#設計模式之四建造者模式(Builder Pattern)【創(chuàng )建型】? 建造者模式-C#改良實(shí)現
建造者模式主要用于“分步驟來(lái)構建一個(gè)復雜的對象”,針對的產(chǎn)品/對象的構建過(guò)程。
微軟FCL中的StringBuilder類(lèi)的實(shí)現就是變種的Builder模式,其實(shí)現值得借鑒。
建造者模式的實(shí)現與工廠(chǎng)模式的實(shí)現其實(shí)比較相似。在工廠(chǎng)方法模式里,我們關(guān)注的是一個(gè)產(chǎn)品整體,無(wú)須關(guān)心產(chǎn)品的各部分是如何創(chuàng )建出來(lái)的;但在建造者模式中,一個(gè)具體產(chǎn)品的產(chǎn)生是依賴(lài)各個(gè)部件的產(chǎn)生以及裝配順序,它關(guān)注的是“由零件一步一步地組裝出產(chǎn)品對象”。簡(jiǎn)單地說(shuō),工廠(chǎng)模式是一個(gè)對象創(chuàng )建的粗線(xiàn)條應用,建造者模式則是通過(guò)細線(xiàn)條勾勒出一個(gè)復雜對象,關(guān)注的是產(chǎn)品組成部分的創(chuàng )建過(guò)程??蓞⒖?工廠(chǎng)方法模式VS建造者模式
參考資料:模板模式的應用?C#設計模式(14)——模板方法模式
我對模板方法模式的理解就是:抽象類(lèi)和多態(tài)的體現在這個(gè)模板方法中,并得到了完美的實(shí)現與應用。
定義一個(gè)抽象類(lèi),類(lèi)中的抽象方法是可變的,延遲到子類(lèi)中實(shí)現,根據子類(lèi)的行為做不同的實(shí)現。類(lèi)中的非抽象方法則是模板方法,定義了模板的內容和執行順序。其次若是有公共的部分也可以在類(lèi)中的非抽象方法中實(shí)現。
定義對象間的一種一對多的依賴(lài)關(guān)系,當一個(gè)對象的狀態(tài)發(fā)生改變時(shí),所有依賴(lài)于它的對象都得到通知并被自動(dòng)更新。
觀(guān)察者模式有四個(gè)角色:抽象主題、具體主題、抽象觀(guān)察者、具體觀(guān)察者。
抽象主題:把所有觀(guān)察者對象的引用保存到一個(gè)聚集里,每個(gè)主題都可以有任何數量的觀(guān)察者。
具體主題:將有關(guān)狀態(tài)存入具體觀(guān)察者對象;在具體主題內部狀態(tài)改變時(shí),給所有登記過(guò)的觀(guān)察者發(fā)出通知。
抽象觀(guān)察者:為所有的具體觀(guān)察者定義一個(gè)接口,在得到主題通知時(shí)更新自己。
具體觀(guān)察者:實(shí)現抽象觀(guān)察者角色所要求的更新接口,以便使本身的狀態(tài)與主題狀態(tài)協(xié)調。
可參考:C#設計模式-觀(guān)察者模式???觀(guān)察者模式-C#實(shí)現
當一個(gè)對象的內部狀態(tài)改變時(shí)允許改變它的行為。
狀態(tài)模式主要解決的是當控制一個(gè)對象狀態(tài)轉換的條件表達式過(guò)于復雜時(shí)的情況。把狀態(tài)的判斷邏輯轉移到表示不同狀態(tài)的一系列類(lèi)當中,可以把復雜的判斷邏輯簡(jiǎn)化。
Context:狀態(tài)管理器,維護一個(gè)ConcreteState子類(lèi)的實(shí)例,這個(gè)實(shí)例定義了當前的狀態(tài)。
State:抽象狀態(tài)類(lèi),將所有可能的狀態(tài)都抽象為具體的行為(方法)或是狀態(tài)(字段)。
ConcreteState:具體狀態(tài),每一個(gè)子類(lèi)實(shí)現的一個(gè)與Context的一個(gè)狀態(tài)相關(guān)的行為,并完成狀態(tài)的切換。
狀態(tài)模式與策略模式都可以用來(lái)替換掉switch..case或是if...else...冗長(cháng)的條件判斷分支,區別在于,如果條件狀態(tài)之間有關(guān)聯(lián)或是依賴(lài)關(guān)系,比如賓館房間的狀態(tài),銀行賬戶(hù)的狀態(tài)等之間有關(guān)聯(lián)及依賴(lài)關(guān)系,此時(shí)應該用狀態(tài)模式來(lái)做切換替代,但是對于條件狀態(tài)之間沒(méi)有什么關(guān)系的比如,快遞點(diǎn)的選擇等選擇性的條件狀態(tài),使用策略模式比較合適。
狀態(tài)模式替換switch...case可參考 C#設計模式--狀態(tài)模式?策略模式替換switch...case...可參考 策略模式重構switch/case分支代碼
三個(gè)角色:代理接口、委托類(lèi)、代理類(lèi)。
委托類(lèi)是代理接口的具體實(shí)現,而代理類(lèi)主要負責為委托類(lèi)預處理消息、過(guò)濾消息、把消息轉發(fā)給委托類(lèi)、以及事后處理消息等。代理類(lèi)同樣也實(shí)現代理接口,只是代理類(lèi)的對象并不真正實(shí)現服務(wù),而是通過(guò)調用委托類(lèi)的對象的相關(guān)方法來(lái)提供特定的服務(wù)。
動(dòng)態(tài)代理:代理類(lèi)在程序運行時(shí)創(chuàng )建的代理方式。
如果委托類(lèi)很多的話(huà),那么靜態(tài)代理的方式將會(huì )產(chǎn)生大量的代理類(lèi),這不利于維護,會(huì )產(chǎn)生多個(gè)弊端,所以就有了動(dòng)態(tài)代理。
動(dòng)態(tài)代理與AOP緊密相關(guān),AOP說(shuō)白了就是在某個(gè)實(shí)例方法的調用前后增加相應地業(yè)務(wù)邏輯或是處理邏輯,為了方便以及實(shí)際的開(kāi)發(fā),我們會(huì )創(chuàng )建某個(gè)實(shí)例類(lèi)的動(dòng)態(tài)實(shí)例,這就是動(dòng)態(tài)代理的作用了,其次在動(dòng)態(tài)代理中執行指定的方法前后增加邏輯即可,這就是AOP與動(dòng)態(tài)代理的緊密聯(lián)系了。絕大數的框架中,會(huì )創(chuàng )建一個(gè)攔截器,在指定的攔截方法中調用動(dòng)態(tài)代理實(shí)例方法,并增加相應地業(yè)務(wù)邏輯或是處理邏輯即完成了AOP。簡(jiǎn)單的實(shí)現,可以在創(chuàng )建動(dòng)態(tài)代理類(lèi)實(shí)例調用指定方法的前后增加邏輯即可。
聯(lián)系客服