1. 程式人生 > >行為型設計模式

行為型設計模式

    行為性設計模式涉及到演算法和物件間的職責分配,不僅描述物件或類的模式,還描述它們之間的通訊方式。它們採用繼承機制在類間分派行為,通過合理的處理方法,達到使系統升級性和維護性提高的目的。

    一共包括11種設計模式,分別為:觀察者模式(Observer)、模板方法模式(TemplateMethod)、命令模式(Commander)、狀態模式(State)、職責鏈模式(Chain of Responsibility)、直譯器模式(Interpreter)、中介者模式(Mediator)、訪問者模式(Visitor)、策略模式(Strategy)、備忘錄模式(Memento)、迭代器模式(Iterator),下面分別介紹: 

    1、觀察者模式

    功能:定義物件間的一種一對多的依賴關係,當一個物件的狀態發生變化時,所有依賴於它的物件都得到通知並被自動更新。

    解釋:觀察者模式所作的工作其實就是在解除耦合。讓耦合的雙方都依賴於抽象,而不是依賴於具體(依賴倒轉原則)。從而使得各自的變化都不會影響到另一邊的變化。

    使用動機:將一個系統分割成一系列相互協作的類有一個很不好的副作用,那就是需要維護相關物件間的一致性。我們不希望為了維持一致性而使各類緊密耦合,這樣會給維護、擴充套件和重用都帶來不便。簡而言之即當一個物件的改變需要同時改變其他物件而且它不知道具體有多少物件有待改變時,應該考慮使用觀察者模式。

    

    2、模板方法模式

    功能:定義一個操作的演算法骨架,而將一些步驟延遲到子類中,模板方法使得子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟。

    解釋:通過把不變行為搬移到超類,去除子類中的重複程式碼,提供了一個很好的程式碼複用平臺。其實就是當不變和可變的行為在方法的子類實現中火鶴在一起的時候,不變的行為就會在子類中重複出現。我們通過模板方法模式把這些行為搬移到單一的方法,這樣就幫助子類擺脫重複的不變行為的糾纏。

    使用動機:當我們要完成在某一細節層次一致的一個過程或一系列步驟,但其個別步驟在更詳細的層次上的實現可能不同時,我們通常考慮用模板方法模式來處理。

    

    3、命令模式

    功能:將一個請求封裝為一個物件,從而使你可用不同的請求對客戶進行引數化;可以對請求排隊或記錄請求日誌,以及支援可撤銷的操作。

    優點:a、它能較容易地設計一個命令佇列

                b、在需要的情況下,可以較容易地將命令記入日誌

                c、允許接受請求的一方決定是否要否決請求

                d、可以容易地實現對請求的撤銷和重做

                e、關鍵點:命令模式把請求一個操作的物件與知道怎麼執行一個操作的物件分割開。

    

    4、狀態模式

    功能:允許一個物件在其內部狀態改變時改變它的行為,讓物件看起來似乎修改了它的類。

    解釋:狀態模式主要解決的是當控制一個物件狀態轉換的條件表示式過於複雜時的情況,把狀態的判斷邏輯轉移到表示不同狀態的一系列類當中,可以把複雜的判斷邏輯簡化。說白了,目的就是消除龐大的條件分支語句(與反射功能有些類似)。當然,如果這個狀態判斷很簡單,那就沒必要用‘狀態模式’了。

    優點:可以將特定狀態相關的行為區域性化,並且將不同狀態的行為分割開來。即:將特定的狀態相關的行為都放入一個物件中,由於所有與狀態相關的程式碼都存在於某個ConcreteState中,所以通過定義新的子類可以很容易的增加新的狀態和轉換。

    使用動機:當一個物件的行為取決於它的狀態,並且它必須在執行時刻根據狀態改變它的行為時,就可以考慮使用狀態模式了。

    

    5、職責鏈模式

    功能:使多個物件都有機會處理請求,從而避免請求的傳送者和接收者之間的耦合關係。將這些物件連成一條鏈,並沿著這條鏈傳遞該請求,直到有一個物件處理它為止。

    優點:職責鏈模式可以是的接收者和傳送者都沒有對方的明確資訊,且鏈中的物件自己也並不知道鏈的結構。結果是職責鏈可簡化物件的相互連線,它們僅需要保持一個指向其後繼者的引用,而不需保持它所有的時候選接受者的引用,即:大大降低了耦合度。

                 由於是在客戶端來定義鏈的結構,故可以隨時地增加或修改處理一個請求的結構。增強了給物件指派職責的靈活性。

    

    6、直譯器模式

    功能:給定一個語言,定義它的文法的一種表示,並定義一個直譯器,這個直譯器使用該表示來解釋語言中的句子。

    優點:可以很容易地改變和擴充套件文法,因為該模式使用類來表示文法規則,故可使用繼承來改變或擴充套件文法;也比較容易擴充套件文法,因為定義抽象語法樹種各個節點的類的實現大體類似,這些類都易於直接編寫。

    缺點:直譯器模式為文法中的每一條規則至少定義了一個類,因此包含許多規則的文法可能難以維護和管理。建議當文法非常複雜時,使用其他的技術如語法分析程式或編譯器生成器來處理。

    使用動機:如果一種特定型別的問題發生的頻率足夠高,那麼可能就值得將該問題的各個勢力表述為一個簡單語言中的巨資。這樣就可以構建一個直譯器,該直譯器通過解釋那些句子來解決該問題。

    

    7、中介者模式

    功能:用一箇中介物件來封裝一系列的物件互動。中介者使各物件不需要顯示地相互引用、從而使其耦合鬆散,而且可以獨立地改變他們之間的互動。

    優點:1、Mediator的出現減少了哥哥Colleague的耦合,使得可以獨立地改變和服用各個Colleague類和Mediator。

                2、由於把物件如何協作進行了抽象,將終結作為一個獨立的概念並將其封裝在一個物件中,這樣關注的物件就從物件各自本身的行為轉移到他們之間的互動上來,也

                      就是站在一個更巨集觀的角度去看待系統。

    缺點:由於ConcreteMediator控制了集中化,於是就把互動複雜性變為了中介者的複雜性,這就使得中介者會變得比任何一個ConcreteColleague都複雜。

    使用動機:中介者模式一般用於一組物件以定義良好但是複雜的方式進行通訊的場合,以及向定製一個分部在多個類中的行為,而不像生成太多的子類的場合。

    

    8、訪問者模式

    功能:表示一個作用於某物件結構中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用於這些元素的新操作。

    優點:增加新的操作很容易,因為增加新的操作就意味著增加一個新的訪問者。訪問者模式將有關的行為集中到一個訪問者物件中。

    缺點:增加新的資料結構比較困難。

    使用動機:訪問者模式的目的是把處理從資料結構分離開來。如果有比較穩定的資料結構,又有易於變化的演算法的話,使用反問著模式比較合適。因為訪問者模式使得演算法操作的增加變得容易。

    

    9、策略模式

    功能:定義一系列的演算法,把他們一個個封裝起來,並且使它們可相互轉換。本模式使得演算法可獨立於使用它的客戶而變化。

    解釋:策略模式是一種定義一系列演算法的方法,從概念上來看,所有這些演算法完成的都是相同的工作,只是實現不同,它可以以相同的方式呼叫所有的演算法,減少了各種演算法類與使用演算法類之間的耦合。

    優點:1、策略模式的Strategy類層次為Context定義了一系列的可供重用的演算法或行為。繼承有助於析取出這些演算法中的公共功能。

                2、簡化了單元測試,因為每個演算法都有自己的類可以通過自己的介面單獨測試。

    實際應用:策略模式+簡單工程模式+反射+配置檔案可解除客戶端需要選擇判斷的弊病。

    

    10、備忘錄模式

    定義:在不破壞封裝性的前提下,捕獲一個物件的內部狀態,並在改物件之外儲存這個狀態。這樣以後就可將該物件恢復到原先儲存的狀態。

    優點:1、使用備忘錄可以把複雜的物件內部資訊對其他的物件遮蔽起來,從而可以恰當的保持封裝的邊界。

                2、當角色的狀態改變的時候,有可能這個狀態無效,這時候就可以使用暫時儲存起來的備忘錄將狀態復原。

    缺點:角色狀態需要完整儲存到備忘錄物件中,如果狀態資料很大很多,那麼在資源消耗上,備忘錄物件會非常耗記憶體。

    使用動機:Memento模式比較適用於功能比較複雜的,但需要維護或記錄屬性歷史的類,或者需要儲存的屬性只是眾多屬性中的一小部分時,Originator可以根據儲存的Memento資訊還原到前一狀態。

    

    11、迭代器模式

    功能:提供一種方法順序訪問一個聚合物件中各個元素,而又不需暴露該物件的內部表示。

    解釋:迭代器模式就是分離了集合物件的遍歷行為,抽象出一個迭代器來負責,這樣既可以做到不暴露集合的內部結果,又可讓外部程式碼透明地訪問集合內部的資料。

    使用動機:當需要訪問一個聚集物件,而且不管這些物件是什麼都需要遍歷的時候,就應該考慮用迭代器模式;當需要對聚集有多種方式遍歷時,可以考慮使用迭代器模式。