23種設計模式----行為型模式


行為型模式分為類行為模式和對象行為模式,前者采用繼承機制來在類間分派行為,后者采用組合或聚合在對象間分配行為。由於組合關系或聚合關系比繼承關系耦合度低,滿足“合成復用原則”,所以對象行為模式比類行為模式具有更大的靈活性。它包含以下 11 種模式:

  1. 模板方法(Template Method)模式:定義一個操作中的算法骨架,將算法的一些步驟延遲到子類中,使得子類在可以不改變該算法結構的情況下重定義該算法的某些特定步驟。
  2. 策略(Strategy)模式:定義了一系列算法,並將每個算法封裝起來,使它們可以相互替換,且算法的改變不會影響使用算法的客戶。
  3. 命令(Command)模式:將一個請求封裝為一個對象,使發出請求的責任和執行請求的責任分割開。
  4. 職責鏈(Chain of Responsibility)模式:把請求從鏈中的一個對象傳到下一個對象,直到請求被響應為止。通過這種方式去除對象之間的耦合。
  5. 狀態(State)模式:允許一個對象在其內部狀態發生改變時改變其行為能力。
  6. 觀察者(Observer)模式:多個對象間存在一對多關系,當一個對象發生改變時,把這種改變通知給其他多個對象,從而影響其他對象的行為。
  7. 中介者(Mediator)模式:定義一個中介對象來簡化原有對象之間的交互關系,降低系統中對象間的耦合度,使原有對象之間不必相互了解。
  8. 迭代器(Iterator)模式:提供一種方法來順序訪問聚合對象中的一系列數據,而不暴露聚合對象的內部表示。
  9. 訪問者(Visitor)模式:在不改變集合元素的前提下,為一個集合中的每個元素提供多種訪問方式,即每個元素有多個訪問者對象訪問。
  10. 備忘錄(Memento)模式:在不破壞封裝性的前提下,獲取並保存一個對象的內部狀態,以便以后恢復它。
  11. 解釋器(Interpreter)模式:提供如何定義語言的文法,以及對語言句子的解釋方法,即解釋器。

1. 模板方法模式

模板方法(Template Method)模式的定義如下:定義一個操作中的算法骨架,而將算法的一些步驟延遲到子類中,使得子類可以不改變該算法結構的情況下重定義該算法的某些特定步驟。它是一種類行為型模式。

主要角色

  1. 抽象類(Abstract Class):負責給出一個算法的輪廓和骨架。它由一個模板方法和若干個基本方法構成。
  2. 具體子類(Concrete Class):實現抽象類中所定義的抽象方法和鈎子方法,它們是一個頂級邏輯的一個組成步驟。

應用場景

  • 算法的整體步驟很固定,但其中個別部分易變時,這時候可以使用模板方法模式,將容易變的部分抽象出來,供子類實現。
  • 當多個子類存在公共的行為時,可以將其提取出來並集中到一個公共父類中以避免代碼重復。首先,要識別現有代碼中的不同之處,並且將不同之處分離為新的操作。最后,用一個調用這些新的操作的模板方法來替換這些不同的代碼。
  • 當需要控制子類的擴展時,模板方法只在特定點調用鈎子操作,這樣就只允許在這些點進行擴展。

2. 策略模式

策略(Strategy)模式的定義:該模式定義了一系列算法,並將每個算法封裝起來,使它們可以相互替換,且算法的變化不會影響使用算法的客戶。

主要角色

  1. 抽象策略(Strategy)類:定義了一個公共接口,各種不同的算法以不同的方式實現這個接口,環境角色使用這個接口調用不同的算法,一般使用接口或抽象類實現。
  2. 具體策略(Concrete Strategy)類:實現了抽象策略定義的接口,提供具體的算法實現。
  3. 環境(Context)類:持有一個策略類的引用,最終給客戶端調用。

應用場景

  • 一個系統需要動態地在幾種算法中選擇一種時,可將每個算法封裝到策略類中。
  • 一個類定義了多種行為,並且這些行為在這個類的操作中以多個條件語句的形式出現,可將每個條件分支移入它們各自的策略類中以代替這些條件語句。
  • 系統中各算法彼此完全獨立,且要求對客戶隱藏具體算法的實現細節時。
  • 系統要求使用算法的客戶不應該知道其操作的數據時,可使用策略模式來隱藏與算法相關的數據結構。
  • 多個類只區別在表現行為不同,可以使用策略模式,在運行時動態選擇具體要執行的行為。

3. 命令模式

命令(Command)模式的定義如下:將一個請求封裝為一個對象,使發出請求的責任和執行請求的責任分割開。這樣兩者之間通過命令對象進行溝通,這樣方便將命令對象進行儲存、傳遞、調用、增加與管理。

主要角色

  1. 抽象命令類(Command)角色:聲明執行命令的接口,擁有執行命令的抽象方法 execute()。
  2. 具體命令角色(Concrete    Command)角色:是抽象命令類的具體實現類,它擁有接收者對象,並通過調用接收者的功能來完成命令要執行的操作。
  3. 實現者/接收者(Receiver)角色:執行命令功能的相關操作,是具體命令對象業務的真正實現者。
  4. 調用者/請求者(Invoker)角色:是請求的發送者,它通常擁有很多的命令對象,並通過訪問命令對象來執行相關請求,它不直接訪問接收者。

應用場景

  • 當系統需要將請求調用者與請求接收者解耦時,命令模式使得調用者和接收者不直接交互。
  • 當系統需要隨機請求命令或經常增加或刪除命令時,命令模式比較方便實現這些功能。
  • 當系統需要執行一組操作時,命令模式可以定義宏命令來實現該功能。
  • 當系統需要支持命令的撤銷(Undo)操作和恢復(Redo)操作時,可以將命令對象存儲起來,采用備忘錄模式來實現。

4. 職責鏈模式

責任鏈(Chain of Responsibility)模式的定義:為了避免請求發送者與多個請求處理者耦合在一起,將所有請求的處理者通過前一對象記住其下一個對象的引用而連成一條鏈;當有請求發生時,可將請求沿着這條鏈傳遞,直到有對象處理它為止。

主要角色

  1. 抽象處理者(Handler)角色:定義一個處理請求的接口,包含抽象處理方法和一個后繼連接。
  2. 具體處理者(Concrete Handler)角色:實現抽象處理者的處理方法,判斷能否處理本次請求,如果可以處理請求則處理,否則將該請求轉給它的后繼者。
  3. 客戶類(Client)角色:創建處理鏈,並向鏈頭的具體處理者對象提交請求,它不關心處理細節和請求的傳遞過程。

應用場景

  • 有多個對象可以處理一個請求,哪個對象處理該請求由運行時刻自動確定。
  • 可動態指定一組對象處理請求,或添加新的處理者。
  • 在不明確指定請求處理者的情況下,向多個處理者中的一個提交請求。

5. 狀態模式

狀態(State)模式的定義:對有狀態的對象,把復雜的“判斷邏輯”提取到不同的狀態對象中,允許狀態對象在其內部狀態發生改變時改變其行為。

主要角色

  1. 環境(Context)角色:也稱為上下文,它定義了客戶感興趣的接口,維護一個當前狀態,並將與狀態相關的操作委托給當前狀態對象來處理。
  2. 抽象狀態(State)角色:定義一個接口,用以封裝環境對象中的特定狀態所對應的行為。
  3. 具體狀態(Concrete    State)角色:實現抽象狀態所對應的行為。

應用場景

  • 當一個對象的行為取決於它的狀態,並且它必須在運行時根據狀態改變它的行為時,就可以考慮使用狀態模式。
  • 一個操作中含有龐大的分支結構,並且這些分支決定於對象的狀態時。

6. 觀察者模式

觀察者(Observer)模式的定義:指多個對象間存在一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴於它的對象都得到通知並被自動更新。

主要角色

  1. 抽象主題(Subject)角色:也叫抽象目標類,它提供了一個用於保存觀察者對象的聚集類和增加、刪除觀察者對象的方法,以及通知所有觀察者的抽象方法。
  2. 具體主題(Concrete    Subject)角色:也叫具體目標類,它實現抽象目標中的通知方法,當具體主題的內部狀態發生改變時,通知所有注冊過的觀察者對象。
  3. 抽象觀察者(Observer)角色:它是一個抽象類或接口,它包含了一個更新自己的抽象方法,當接到具體主題的更改通知時被調用。
  4. 具體觀察者(Concrete Observer)角色:實現抽象觀察者中定義的抽象方法,以便在得到目標的更改通知時更新自身的狀態。

應用場景

  • 對象間存在一對多關系,一個對象的狀態發生改變會影響其他對象。
  • 當一個抽象模型有兩個方面,其中一個方面依賴於另一方面時,可將這二者封裝在獨立的對象中以使它們可以各自獨立地改變和復用。

7. 中介者模式

中介者(Mediator)模式的定義:定義一個中介對象來封裝一系列對象之間的交互,使原有對象之間的耦合松散,且可以獨立地改變它們之間的交互。

主要角色

  1. 抽象中介者(Mediator)角色:它是中介者的接口,提供了同事對象注冊與轉發同事對象信息的抽象方法。
  2. 具體中介者(ConcreteMediator)角色:實現中介者接口,定義一個 List 來管理同事對象,協調各個同事角色之間的交互關系,因此它依賴於同事角色。
  3. 抽象同事類(Colleague)角色:定義同事類的接口,保存中介者對象,提供同事對象交互的抽象方法,實現所有相互影響的同事類的公共功能。
  4. 具體同事類(Concrete Colleague)角色:是抽象同事類的實現者,當需要與其他同事對象交互時,由中介者對象負責后續的交互。

應用場景

  • 當對象之間存在復雜的網狀結構關系而導致依賴關系混亂且難以復用時。
  • 當想創建一個運行於多個類之間的對象,又不想生成新的子類時。

8. 迭代器模式

迭代器(Iterator)模式的定義:提供一個對象來順序訪問聚合對象中的一系列數據,而不暴露聚合對象的內部表示。

主要角色

  1. 抽象聚合(Aggregate)角色:定義存儲、添加、刪除聚合對象以及創建迭代器對象的接口。
  2. 具體聚合(ConcreteAggregate)角色:實現抽象聚合類,返回一個具體迭代器的實例。
  3. 抽象迭代器(Iterator)角色:定義訪問和遍歷聚合元素的接口,通常包含 hasNext()、first()、next() 等方法。
  4. 具體迭代器(Concretelterator)角色:實現抽象迭代器接口中所定義的方法,完成對聚合對象的遍歷,記錄遍歷的當前位置。

應用場景

  • 當需要為聚合對象提供多種遍歷方式時。
  • 當需要為遍歷不同的聚合結構提供一個統一的接口時。
  • 當訪問一個聚合對象的內容而無須暴露其內部細節的表示時。

9. 訪問者模式

訪問者(Visitor)模式的定義:將作用於某種數據結構中的各元素的操作分離出來封裝成獨立的類,使其在不改變數據結構的前提下可以添加作用於這些元素的新的操作,為數據結構中的每個元素提供多種訪問方式。它將對數據的操作與數據結構進行分離,是行為類模式中最復雜的一種模式。

主要角色

  1. 抽象訪問者(Visitor)角色:定義一個訪問具體元素的接口,為每個具體元素類對應一個訪問操作 visit() ,該操作中的參數類型標識了被訪問的具體元素。
  2. 具體訪問者(ConcreteVisitor)角色:實現抽象訪問者角色中聲明的各個訪問操作,確定訪問者訪問一個元素時該做什么。
  3. 抽象元素(Element)角色:聲明一個包含接受操作 accept() 的接口,被接受的訪問者對象作為 accept() 方法的參數。
  4. 具體元素(ConcreteElement)角色:實現抽象元素角色提供的 accept() 操作,其方法體通常都是 visitor.visit(this) ,另外具體元素中可能還包含本身業務邏輯的相關操作。
  5. 對象結構(Object Structure)角色:是一個包含元素角色的容器,提供讓訪問者對象遍歷容器中的所有元素的方法,通常由 List、Set、Map 等聚合類實現。

應用場景

  • 對象結構相對穩定,但其操作算法經常變化的程序。
  • 對象結構中的對象需要提供多種不同且不相關的操作,而且要避免讓這些操作的變化影響對象的結構。
  • 對象結構包含很多類型的對象,希望對這些對象實施一些依賴於其具體類型的操作。

10. 備忘錄模式

備忘錄(Memento)模式的定義:在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象之外保存這個狀態,以便以后當需要時能將該對象恢復到原先保存的狀態。

主要角色

  1. 發起人(Originator)角色:記錄當前時刻的內部狀態信息,提供創建備忘錄和恢復備忘錄數據的功能,實現其他業務功能,它可以訪問備忘錄里的所有信息。
  2. 備忘錄(Memento)角色:負責存儲發起人的內部狀態,在需要的時候提供這些內部狀態給發起人。
  3. 管理者(Caretaker)角色:對備忘錄進行管理,提供保存與獲取備忘錄的功能,但其不能對備忘錄的內容進行訪問與修改。

應用場景

  • 需要保存與恢復數據的場景,如玩游戲時的中間結果的存檔功能。
  • 需要提供一個可回滾操作的場景,如 Word、記事本、Photoshop,Eclipse 等軟件在編輯時按 Ctrl+Z 組合鍵,還有數據庫中事務操作。

11 解釋器模式

解釋器(Interpreter)模式的定義:給分析對象定義一個語言,並定義該語言的文法表示,再設計一個解析器來解釋語言中的句子。也就是說,用編譯語言的方式來分析應用中的實例。這種模式實現了文法表達式處理的接口,該接口解釋一個特定的上下文。

主要角色

  1. 抽象表達式(Abstract Expression)角色:定義解釋器的接口,約定解釋器的解釋操作,主要包含解釋方法 interpret()。
  2. 終結符表達式(Terminal    Expression)角色:是抽象表達式的子類,用來實現文法中與終結符相關的操作,文法中的每一個終結符都有一個具體終結表達式與之相對應。
  3. 非終結符表達式(Nonterminal Expression)角色:也是抽象表達式的子類,用來實現文法中與非終結符相關的操作,文法中的每條規則都對應於一個非終結符表達式。
  4. 環境(Context)角色:通常包含各個解釋器需要的數據或是公共的功能,一般用來傳遞被所有解釋器共享的數據,后面的解釋器可以從這里獲取這些值。
  5. 客戶端(Client):主要任務是將需要分析的句子或表達式轉換成使用解釋器對象描述的抽象語法樹,然后調用解釋器的解釋方法,當然也可以通過環境角色間接訪問解釋器的解釋方法。

應用場景

  • 當語言的文法較為簡單,且執行效率不是關鍵問題時。
  • 當問題重復出現,且可以用一種簡單的語言來進行表達時。
  • 當一個語言需要解釋執行,並且語言中的句子可以表示為一個抽象語法樹的時候,如 XML 文檔解釋。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM