行爲型模式是對在不一樣對象之間劃分責任和算法的抽象化。正則表達式
行爲模式不只僅關於類和對象,還關於它們之間的相互做用。算法
行爲型模式又分爲類的行爲模式和對象的行爲模式兩種。編程
行爲型模式包括11種模式: 模板方法模式、命令模式、迭代器模式、觀察者模式、中介者模式、狀態模式、策略模式、責任鏈模式、訪問者模式、解釋器模式、備忘錄模式數據結構
在一個抽象類中定義一個操做算法的骨架,將一些步驟延遲到子類中去實現。模板方法使得子類能夠在不改變算法結構的情冴下,從新定義算法中的某些步驟。框架
一般咱們會遇到這樣的一個問題:咱們知道一個算法所需的關鍵步聚,並肯定了這些步聚的執行順序。可是某些步聚的具體實現是未知的,或者是某些步聚的實現與具體的環境相關。工具
模板方法模式把咱們不知道具體實現的步聚封裝成抽象方法,提供一些按正確順序調用它們的具體方法(這些具體方法統稱爲模板方法),這樣構成一個抽象基類,子類經過繼承這個抽象基類去實現各個步聚的抽象方法,而工做流程卻由父類來控制。性能
定不變的封裝到抽象類中,須要改變的在子類中去實現。.net
經常使用場景:一批子類的功能有可提取的公共算法骨架設計
選擇關鍵點:算法骨架是否牢固server
命令模式的本質是對命令進行封裝,將發出命令的責任和執行命令的責任分割開
每個命令都是一個操做:請求的一方發出請求,要求執行一個操做;接收的一方收到請求,並執行操做。
命令模式容許請求的一方和接收的一方獨立開來,使得請求的一方沒必要知道接收請求的一方的接口,更沒必要知道請求是怎麼被接收,以及操做是否被執行、什麼時候被執行,以及是怎麼被執行的。
命令模式的關鍵在於引入了抽象命令接口,且發送者針對抽象命令接口編程,只有實現了抽象命令接口的具體命令才能與接收者相關聯。
迭代器模式提供了一種方法順序訪問一個聚合對象(理解爲集合對象)中各個元素,而又無需暴露該對象的內部表示,這樣既能夠作到不暴露集合的內部結構,又可以讓外部代碼透明地訪問集合內部的數據。 迭代器模式爲遍歷不一樣的彙集結構提供如開始、下一個、是否結束、當前哪一項等統一的接口。
當你須要訪問一個聚合對象,並且無論這些對象是什麼都須要遍歷的時候,就應該考慮使用迭代器模式。另外,當須要對彙集有多種方式遍歷時,能夠考慮去使用迭代器模式。
聚合對象,如須要操做。則額外創建一個迭代器類。對集合進行操做處理,其實.net框架已經準備好了迭代器接口,只須要實現接口就好了IEumerator 支持對非泛型集合的簡單迭代。
使用迭代器的好處就是在於保持良好的封裝的同時對集合元素進行循環操做。不須要把數據集合展示給外部對象。不使用迭代器,外部對象會經過getter的方法獲取數據集合而後遍歷,這樣把整個數據集合公開了,而且外部對象能夠直接改寫,另外遍歷數據集合時也要知道數據結構,先分析數據結構才能進行迭代代碼的書寫,這樣若是下次須要修改數據結構時,代碼修改也會變的困難。
觀察者模式又叫發佈訂閱模式,定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象,這個主題對象在狀態發生變化時,會通知全部觀察者對象,使它們可以自動更新本身的行爲。
將一個系統分割成一系列相互協做的類有一個很很差的反作用,那就是須要維護相關對象間的一致性,咱們不但願爲了維持一致性而使各個類緊密耦合,這樣會給維護,擴展和重用都帶來不便。而觀察者模式的關鍵對象是主題Subject和觀察者Obverser,一個Subject能夠任意數目依賴它的Obverser,一旦Subject的狀態發生變化,全部的Obverser都合一獲得通知。Subject發出通知時,並不須要知道誰是它的觀察者,也就是說,具體觀察者是誰,它根本不須要知道,而任何一個具體的觀察者不知道也不須要知道其餘觀察者的存在。
Subject類是把因此觀察者對象的引用保存在一個彙集裏,每一個主體均可以有任意數量的觀察者,抽象主體提供一個藉口,能夠增長和刪除觀察者對象.是個主題或者抽象統治者,Obverser類是抽象觀察者,爲全部的具體觀察者定義一個接口,在獲得主題的通知時更新本身,ConcreteSubject類是具體主題,講有關狀態存入具體觀察者對象,在具體主題的內部狀態改變時,給全部登記過的觀察者發出通知,ConcreteObserver類是具體觀察者,實現抽象觀察者所要求的更新接口,一遍使自己的狀態與主題的狀態相協調
觀察者模式所作的工做其實就是在解除耦合,讓耦合的雙方都依賴於抽象,而不是依賴於具體,從而使得各自的變化都不會影響另外一邊的變化。
當一個對象的改編須要同時改變其餘對象的時候,並且它不知道具體有多少對象有待改變時,應該考慮使用觀察者模式。須要將觀察者與被觀察者解耦或是觀察者的種類不肯定
選擇關鍵點:觀察者與被觀察者是不是多對一的關係
定義了一箇中介對象來封裝一系列對象之間的交互關係。中介者使各個對象之間不須要顯式地相互引用,從而使耦合性下降,並且能夠獨立地改變它們之間的交互行爲
對象與對象之間存在大量的關聯關係,這樣勢必會致使系統的結構變得很複雜,同時若一個對象發生改變,咱們也須要跟蹤與之相關聯的對象,同時作出相應的處理。同時若一個對象發生改變,咱們也須要跟蹤與之相關聯的對象,同時作出相應的處理。系統的可擴展性低。增長一個新的對象,咱們須要在其相關連的對象上面加上引用,這樣就會致使系統的耦合性增高,使系統的靈活性和可擴展都下降。
封裝一箇中介對象來封裝系列對象之間的交互。中介者使各個對象不須要顯示地相互引用,從而使其耦合性鬆散,並且能夠獨立地改變他們之間的交互
由此咱們能夠看出中介者對象封裝了對象之間的關聯關係,致使中介者對象變得比較龐大,所承擔的責任也比較多,它須要知道各個對象交互的細節,若是它出現問題,將致使整個系統的癱瘓。故當系統中出現「多對多」的交互複雜的關係羣時,千萬彆着急使用中介者模式,須要先分析下在設計上是否合理
主要包括抽象中介者和具體中介者 抽象同事類 和具體同事類
當一個對象的行爲取決於它的狀態,而且它必須在運行時刻根據狀態改變它的行爲時,就能夠考慮使用狀態模式了
所謂的狀態模式是容許對象在內部狀態發生改變時改變它的行爲,對象看起來好像修改了它的類
狀態模式主要解決的是當控制一個對象狀態轉換的條件表達式國語複雜時的狀況,把狀態的判斷邏輯轉移到表示不一樣狀態的一系列類當中,能夠把複雜的判斷邏輯簡化。固然,若是這個狀態判斷 很簡單,那就沒有必要用狀態模式了。狀態模式的好處就是將與特定狀態相關的行爲局部化,而且將不一樣狀態的行爲分隔開來
因爲狀態的改變,會改變派生類,產生不一樣的重載方法。
經常使用場景:一個對象在多個狀態下行爲不一樣,且這些狀態可互相轉換
選擇關鍵點:這些狀態是否常常在運行時須要在不一樣的動態之間相互切換
狀態模式與職責鏈模式的區別:狀態模式是讓各個狀態對象本身知道其下一個處理的對象是誰,即在編譯時便設定好了的;而職責鏈模式中的各個對象並不指定其下一個處理的對象究竟是誰,只有在客戶端才設定。
策略模式是針對一組算法,將每一個算法封裝到具備公共接口的獨立的類中,從而使它們能夠相互替換。策略模式使得算法能夠在不影響到客戶端的狀況下發生變化。
定義了一個公共接口,各類不一樣的算法以不一樣的方式實現這個接口,Context使用這個接口調用不一樣的算法,通常使用接口或抽象類實現。
應用場景:
策略模式提供了管理相關的算法族的辦法。策略類的等級結構定義了一個算法或行爲族。恰當使用繼承能夠把公共的代碼轉移到父類裏面,從而避免重複的代碼。
策略模式提供了能夠替換繼承關係的辦法。繼承能夠處理多種算法或行爲。若是不是用策略模式,那麼使用算法或行爲的環境類就可能會有一些子類,每個子類提供一個不一樣的算法或行爲。可是,這樣一來算法或行爲的使用者就和算法或行爲自己混在一塊兒。決定使用哪種算法或採起哪種行爲的邏輯就和算法或行爲的邏輯混合在一塊兒,從而不可能再獨立演化。繼承使得動態改變算法或行爲變得不可能。
使用策略模式能夠避免使用多重條件轉移語句。多重轉移語句不易維護,它把採起哪種算法或採起哪種行爲的邏輯與算法或行爲的邏輯混合在一塊兒,通通列在一個多重轉移語句裏面,比使用繼承的辦法還要原始和落後。
客戶端必須知道全部的策略類,並自行決定使用哪個策略類。這就意味着客戶端必須理解這些算法的區別,以便適時選擇恰當的算法類。換言之,策略模式只適用於客戶端知道全部的算法或行爲的狀況。策略模式形成不少的策略類,每一個具體策略類都會產生一個新類。有時候能夠經過把依賴於環境的狀態保存到客戶端裏面,而將策略類設計成可共享的,這樣策略類實例能夠被不一樣客戶端使用。換言之,可使用享元模式來減小對象的數量。
責任鏈模式(Chain of Responsibility Pattern)爲請求建立了一個接收者對象的鏈。這種模式給予請求的類型,對請求的發送者和接收者進行解耦。
某個請求須要多個對象進行處理,從而避免請求的發送者和接收之間的耦合關係。將這些對象連成一條鏈子,並沿着這條鏈子傳遞該請求,直到有對象處理它爲止。這些對象由每個對象對其下家的引用而鏈接起來造成一條鏈。一般每一個接收者都包含對另外一個接收者的引用。若是一個對象不能處理該請求,那麼它會把相同的請求傳給下一個接收者,依此類推。
經常使用場景:一個請求的處理須要多個對象當中的一個或幾個協做處理。
優勢:下降耦合度。它將請求的發送者和接收者解耦。簡化了對象。使得對象不須要知道鏈的結構。增長新的請求處理類很方便。加強給對象指派職責的靈活性。經過改變鏈內的成員或者調動它們的次序,容許動態地新增或者刪除責任。
可是不能保證請求必定被接收。可能不容易觀察運行時的特徵,有礙於除錯。
訪問者模式就是表示一個做用於某對象結構中的各元素的操做。它使你能夠在不改變各元素的類的前提下定義做用於這些元素的新操做。
訪問者適合於數據結構相對比較穩定的系統,主要是把處理從數據結構分離出來,不少系統能夠按照算法和數據結構分開,若是這樣的系統有比較穩定的數據結構,又有易於變化的算法的話,使用訪問者模式就比較合適,由於訪問者模式使得算法的增長變得容易。
訪問者模式的優勢是增長新的操做很容易,由於增長新的操做就意味這增長了一個新的訪問者,訪問者模式將有關的行爲集中到一個訪問者對象中
訪問者的缺點實際上是使增長新的數據結構變的很困難
在不破壞封裝的前提下,捕獲一個對象的內部狀態,並在該對象以外保存這個狀態,這樣之後就能夠把該對象恢復到原先的狀態。發起人能夠根據須要決定備忘錄存儲本身的哪些內部狀態。
經常使用場景:須要在對象的外部保存該對象的內部狀態
解釋器模式描述瞭如何爲簡單的語言定義一個文法,如何在該語言中表示一個句子,以及如何解釋這些句子。
.當有一個語言須要解釋執行,而且你可將該語言中的句子表示爲一個抽象語法樹,可使用解釋器模式。而當存在如下狀況時該模式效果最好
解釋器模式真的是一個比較少用的模式,由於對它的維護實在是太麻煩了,想象一下,一坨一坨的非終結符解釋器,假如不是事先對文法的規則瞭如指掌,或者是文法特別簡單,則很難讀懂它的邏輯。解釋器模式在實際的系統開發中使用的不多,由於他會引發效率、性能以及維護等問題,儘可能不要在重要模塊中使用解釋器模式,由於維護困難。在項目中,可使用腳本語言來代替解釋器模