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

設計模式---行為型

設計模式—行為型

行為型模式一共有11種:

  • 策略模式(Strategy)
  • 模板方法模式(Template Method)
  • 命令模式(Command)
  • 中介者模式(Mediator)
  • 觀察者模式(Observer)
  • 迭代器模式(Iteratior)
  • 訪問者模式(Visiter)
  • 職責鏈模式(Chain of Responsibility)
  • 備忘錄模式(Memento)
  • 狀態模式(State)
  • 直譯器模式(Interpreter)
      其中有分為:
      演算法封裝:模板方法、策略、命令模式
      物件去耦:中介、觀察者模式
      抽象集合:迭代器模式
      行為擴充套件:訪問者、職責鏈模式
      物件狀態:狀態模式
      直譯器模式

模板方法模式(Template Method)
1.定義:
定義一個操作中演算法的骨架,而將一些步驟延遲到子類中。模板方法使子類可以重定義演算法的某些特定步驟而不改變該演算法的結構。(定義一個模板結構,具體內容子類去實現)
2.作用:
提高程式碼複用性 ,將相同部分的程式碼放在抽象的父類中,而將不同的程式碼放入不同的子類中。
實現了反向控制 ,通過一個父類呼叫其子類的操作,通過對子類的具體實現擴充套件不同的行為,實現了反向控制 & 符合“開閉原則”。
3.結構圖
在這裡插入圖片描述
4.優缺點
優點:
提高程式碼複用性 ,將相同部分的程式碼放在抽象的父類中。
提高了拓展性 ,將不同的程式碼放入不同的子類中,通過對子類的擴充套件增加新的行為。
實現了反向控制 ,通過一個父類呼叫其子類的操作,通過對子類的擴充套件增加新的行為,實現了反向控制 & 符合“開閉原則”。
缺點:
引入了抽象類,每一個不同的實現都需要一個子類來實現,導致類的個數增加,從而增加了系統實現的複雜度。
5.應用場景
一次性實現一個演算法的不變的部分,並將可變的行為留給子類來實現;
各子類中公共的行為應被提取出來並集中到一個公共父類中以避免程式碼重複;
控制子類的擴充套件。

策略模式(Strategy)
1.定義:
它定義了演算法家族,分別封裝起來,讓它們之間可以相互替換,此模式讓演算法的變化,不會影響到使用演算法的客戶。(簡單來說:準備一組演算法 , 將每一個演算法封裝起來,讓外部按需呼叫 ,使得互換)
2.作用
演算法可獨立於使用外部而變化;
客戶端方便根據外部條件選擇不同策略來解決不同問題。
3.結構圖
角色:策略介面(Strategy)、具體策略、環境物件
在這裡插入圖片描述
4.優缺點
優點:
策略類之間可以自由切換,由於策略類都實現同一個介面,所以使它們之間可以自由切換。
易於擴充套件,增加一個新的策略只需要新增一個具體的策略類即可,基本不需要改變原有的程式碼,符合“開閉原則“。
避免使用多重條件選擇語句(if else),充分體現面向物件設計思想。
缺點:
客戶端必須知道所有的策略類,並自行決定使用哪一個策略類。
策略模式將造成產生很多策略類,可以通過使用享元模式在一定程度上減少物件的數量。
5.應用場景
複雜的演算法 / 資料結構
類的行為 / 方法

命令模式(Command)
1.定義
將一個請求封裝為一個物件,從而使你可用不同的請求對客戶進行引數化;對請求排隊或記錄請求日誌,以及支援可撤銷的操作。
2.作用
主要解決的是當控制一個物件狀態轉換的條件表示式過於複雜時的情況。把狀態的判斷邏輯轉移到表示不同狀態的一系列類當中,可以把複雜的判斷邏輯簡化。(消除龐大的條件分支語句)
3.結構圖
角色:客戶端(Client)、命令呼叫者(Invoker)、命令介面(Command)、具體命令(ConcreteCommand)、命令接收者(Receiver)
在這裡插入圖片描述
4.優缺點
優點
將與特定狀態相關的行為區域性化,並且將不同狀態的行為分割開來。
缺點
使用命令模式可能會導致某些系統有過多的具體命令類。因為針對每一個命令都需要設計一個具體命令類,因此某些系統可能需要大量具體命令類,這將影響命令模式的使用。
5.應用場景
系統需要將請求呼叫者和請求接收者解耦,使得呼叫者和接收者不直接互動。
系統需要在不同的時間指定請求、將請求排隊和執行請求。
系統需要支援命令的撤銷(Undo)操作和恢復(Redo)操作。
系統需要將一組操作組合在一起,即支援巨集命令。

中介者模式(Mediator)
1.定義
用一箇中介物件來封裝一系列的物件互動。中介者使各物件不需要顯式地互相吸引,從而使其耦合鬆散,而且可以獨立地改變它們之間的互動。
2.作用
是用來降低多個物件和類之間的通訊複雜性。
3.結構圖
角色:中介者介面(Mediator)、具體中介者、同事者介面(Colleague),具體同事者。
在這裡插入圖片描述
4.優缺點
優點
降低了類的複雜度,將一對多轉化成了一對一。
各個類之間的解耦。
符合迪米特原則。
缺點
中介者會龐大,變得複雜難以維護。
5.應用場景
一組定義良好的物件,現在要進行復雜的相互通訊。
想通過一箇中間類來封裝多個類中的行為,而又不想生成太多的子類。

觀察者模式(Observer)又叫做釋出-訂閱(Publish/Subscribe)模式
1.定義
定義了一種一對多的依賴關係,如果你多個觀察者物件同時監聽某一個主題物件。這個主題物件在狀態發生變化時,會通知所有觀察者物件,使它們能夠自動更新自己。
2.作用
一個物件狀態改變給其他物件通知的問題,而且要考慮到易用和低耦合,保證高度的協作。
3.結構圖
角色:釋出者介面(Subject)、具體釋出者、監聽者介面(Observer)、具體監聽者。
在這裡插入圖片描述
4.優缺點
優點
觀察者和被觀察者是抽象耦合的。
建立一套觸發機制。
缺點
如果一個被觀察者物件有很多的直接和間接的觀察者的話,將所有的觀察者都通知到會花費很多時間。
如果在觀察者和觀察目標之間有迴圈依賴的話,觀察目標會觸發它們之間進行迴圈呼叫,可能導致系統崩潰。
觀察者模式沒有相應的機制讓觀察者知道所觀察的目標物件是怎麼發生變化的,而僅僅只是知道觀察目標發生了變化。
5.應用場景
一個抽象模型有兩個方面,其中一個方面依賴於另一個方面。將這些方面封裝在獨立的物件中使它們可以各自獨立地改變和複用。
一個物件的改變將導致其他一個或多個物件也發生改變,而不知道具體有多少物件將發生改變,可以降低物件之間的耦合度。
一個物件必須通知其他物件,而並不知道這些物件是誰。
需要在系統中建立一個觸發鏈,A物件的行為將影響B物件,B物件的行為將影響C物件……,可以使用觀察者模式建立一種鏈式觸發機制。

迭代器模式(Iteratior)
1.定義
提供一種方法順序訪問一個聚合物件中各個元素,而又不暴露該物件的內部表示。
2.作用
不同的方式來遍歷整個整合物件。
3.結構圖
角色:迭代器、集合
在這裡插入圖片描述
4.優缺點
優點
1、它支援以不同的方式遍歷一個聚合物件。 2、迭代器簡化了聚合類。 3、在同一個聚合上可以有多個遍歷。 4、在迭代器模式中,增加新的聚合類和迭代器類都很方便,無須修改原有程式碼。
缺點
由於迭代器模式將儲存資料和遍歷資料的職責分離,增加新的聚合類需要對應增加新的迭代器類,類的個數成對增加,這在一定程度上增加了系統的複雜性。
5.應用場景
訪問一個聚合物件的內容而無須暴露它的內部表示。
需要為聚合物件提供多種遍歷方式。
為遍歷不同的聚合結構提供一個統一的介面。
6. 注意事項:
迭代器模式就是分離了集合物件的遍歷行為,抽象出一個迭代器類來負責,這樣既可以做到不暴露集合的內部結構,又可讓外部程式碼透明地訪問集合內部的資料。

訪問者模式(Visiter)
1.定義
表示一個作用於某物件結構中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用於這些元素的新操作。
2.作用
穩定的資料結構和易變的操作耦合問題。
3.結構圖
角色:訪問者(Vistor)介面、具體訪問者、訪問元素(Element)介面、具體元素
在這裡插入圖片描述
4.優缺點
優點
符合單一職責原則;優秀的擴充套件性;靈活性。
缺點
具體元素對訪問者公佈細節,違反了迪米特原則。
具體元素變更比較困難。
違反了依賴倒置原則,依賴了具體類,沒有依賴抽象。
5.應用場景
物件結構中物件對應的類很少改變,但經常需要在此物件結構上定義新的操作。
需要對一個物件結構中的物件進行很多不同的並且不相關的操作,而需要避免讓這些操作"汙染"這些物件的類,也不希望在增加新操作時修改這些類。
6.注意事項:
訪問者可以對功能進行統一,可以做報表、UI、攔截器與過濾器。

職責鏈模式(Chain of Responsibility)
1.定義
使多個物件都有機會處理請求,從而避免請求的傳送者和接受者之前的耦合關係。將這個物件連成一天鏈,並沿著這條鏈傳遞該請求,直到有一個物件處理它為止。
2.作用
職責鏈上的處理者負責處理請求,客戶只需要將請求傳送到職責鏈上即可,無須關心請求的處理細節和請求的傳遞,所以職責鏈將請求的傳送者和請求的處理者解耦了。
3.結構圖
在這裡插入圖片描述
4.優缺點
優點
降低耦合度。它將請求的傳送者和接收者解耦。
簡化了物件。使得物件不需要知道鏈的結構。
增強給物件指派職責的靈活性。通過改變鏈內的成員或者調動它們的次序,允許動態地新增或者刪除責任。
增加新的請求處理類很方便。
缺點
不能保證請求一定被接收。
系統性能將受到一定影響,而且在進行程式碼除錯時不太方便,可能會造成迴圈呼叫。
可能不容易觀察執行時的特徵,有礙於除錯。
5.應用場景
有多個物件可以處理同一個請求,具體哪個物件處理該請求由執行時刻自動確定。
在不明確指定接收者的情況下,向多個物件中的一個提交一個請求。
可動態指定一組物件處理請求。

備忘錄模式(Memento)
1.定義
在不破壞封裝性的前提下,捕獲一個物件的內部狀態,並在該物件之外儲存這個狀態。這樣以後就可將該物件恢復到原先儲存的狀態。
2.作用
所謂備忘錄模式就是在不破壞封裝的前提下,捕獲一個物件的內部狀態,並在該物件之外儲存這個狀態,這樣可以在以後將物件恢復到原先儲存的狀態。
3.結構圖
角色:有三個角色:發起人(Originatior)、備忘錄(Memento)、看管人(Caretaker)。
在這裡插入圖片描述
4.優缺點
優點: 1、給使用者提供了一種可以恢復狀態的機制,可以使使用者能夠比較方便地回到某個歷史的狀態。 2、實現了資訊的封裝,使得使用者不需要關心狀態的儲存細節。
缺點:消耗資源。如果類的成員變數過多,勢必會佔用比較大的資源,而且每一次儲存都會消耗一定的記憶體。
5.應用場景: 1、需要儲存/恢復資料的相關狀態場景。 2、提供一個可回滾的操作。

狀態模式(State)
1.定義
當一個物件的內在狀態改變時允許改變其行為,這個物件看起來像是改變了其類。
2.作用
物件的行為依賴於它的狀態(屬性),並且可以根據它的狀態改變而改變它的相關行為。
3.結構圖
角色:環境(context)、狀態(state)
在這裡插入圖片描述
4.優缺點
優點
1、封裝了轉換規則。 2、列舉可能的狀態,在列舉狀態之前需要確定狀態種類。 3、將所有與某個狀態有關的行為放到一個類中,並且可以方便地增加新的狀態,只需要改變物件狀態即可改變物件的行為。 4、允許狀態轉換邏輯與狀態物件合成一體,而不是某一個巨大的條件語句塊。 5、可以讓多個環境物件共享一個狀態物件,從而減少系統中物件的個數。
缺點
1、狀態模式的使用必然會增加系統類和物件的個數。 2、狀態模式的結構與實現都較為複雜,如果使用不當將導致程式結構和程式碼的混亂。 3、狀態模式對"開閉原則"的支援並不太好,對於可以切換狀態的狀態模式,增加新的狀態類需要修改那些負責狀態轉換的原始碼,否則無法切換到新增狀態,而且修改某個狀態類的行為也需修改對應類的原始碼。
5.應用場景
行為隨狀態改變而改變的場景。條件、分支語句的代替者。
6.注意事項:
在行為受狀態約束的時候使用狀態模式,而且狀態不超過 5 個。

直譯器模式(Interpreter)
1.定義
給定一個語言,定義它的文法的一種表示,並定義一個直譯器,這個直譯器使用該表示來解釋語言中的句子。
2.作用
對於一些固定文法構建一個解釋句子的直譯器。
3.結構圖
角色:環境(context)、直譯器
在這裡插入圖片描述
4.優缺點
優點
可擴充套件性比較好,靈活;增加了新的解釋表示式的方式;易於實現簡單文法。
缺點
可利用場景比較少;對於複雜的文法比較難維護;直譯器模式會引起類膨脹;直譯器模式採用遞迴呼叫方法。
5.應用場景
可以將一個需要解釋執行的語言中的句子表示為一個抽象語法樹。
一些重複出現的問題可以用一種簡單的語言來進行表達。
一個簡單語法需要解釋的場景。