您好,登錄后才能下訂單哦!
行為型模式概述
行為型模式(Behavioral Pattern)是對在不同的對象之間劃分責任和算法的抽象化。
行為型模式不僅僅關注類和對象的結構,而且重點關注它們之間的相互作用。
通過行為型模式,可以更加清晰地劃分類與對象的職責,并研究系統在運行時實例對象之間的交互。在系統運行時,對象并不是孤立的,它們可以通過相互通信與協作完成某些復雜功能,一個對象在運行時也將影響到其他對象的運行。
行為型簡介
職責鏈模式(Chain of Responsibility)
命令模式(Command)
解釋器模式(Interpreter)
迭代器模式(Iterator)
中介者模式(Mediator)
備忘錄模式(Memento)
觀察者模式(Observer)
狀態(tài)模式(State)
策略模式(Strategy)
模板方法模式(Template Method)
訪問者模式(Visitor)
1.職責鏈模式
1.1 動機
職責鏈可以是一條直線、一個環(huán)或者一個樹形結構,最常見的職責鏈是直線型,即沿著一條單向的鏈來傳遞請求。
鏈上的每一個對象都是請求處理者,職責鏈模式可以將請求的處理者組織成一條鏈,并使請求沿著鏈傳遞,由鏈上的處理者對請求進行相應的處理,客戶端無須關心請求的處理細節(jié)以及請求的傳遞,只需將請求發(fā)送到鏈上即可,將請求的發(fā)送者和請求的處理者解耦。這就是職責鏈模式的模式動機。
1.2 類圖
Handler: 抽象處理者
ConcreteHandler: 具體處理者
Client: 客戶類
1.3 優(yōu)點
降低耦合度
可簡化對象的相互連接
增強給對象指派職責的靈活性
增加新的請求處理類很方便
1.4缺點
不能保證請求一定被接收。
系統性能將受到一定影響,而且在進行代碼調試時不太方便;可能會造成循環(huán)調用。
1.5情景
有多個對象可以處理同一個請求,具體哪個對象處理該請求由運行時刻自動確定。
在不明確指定接收者的情況下,向多個對象中的一個提交一個請求。
可動態(tài)指定一組對象處理請求。
比如
早期的Java AWT事件模型(JDK 1.0及更早)
Java中的異常處理機制
2.命令模式
2.1 動機
命令模式可以對發(fā)送者和接收者完全解耦,發(fā)送者與接收者之間沒有直接引用關系,發(fā)送請求的對象只需要知道如何發(fā)送請求,而不必知道如何完成請求。這就是命令模式的模式動機。
2.2 類圖
Command: 抽象命令類
ConcreteCommand: 具體命令類
Invoker: 調用者
Receiver: 接收者
Client:客戶類
2.3 優(yōu)點
降低系統的耦合度。
新的命令可以很容易地加入到系統中。
可以比較容易地設計一個命令隊列和宏命令(組合命令)。
可以方便地實現對請求的Undo和Redo。
2.4 缺點
使用命令模式可能會導致某些系統有過多的具體命令類。因為針對每一個命令都需要設計一個具體命令類,因此某些系統可能需要大量具體命令類,這將影響命令模式的使用。
2.5 情景
系統需要將請求調用者和請求接收者解耦,使得調用者和接收者不直接交互。
系統需要在不同的時間指定請求、將請求排隊和執(zhí)行請求。
系統需要支持命令的撤銷(Undo)操作和恢復(Redo)操作。
系統需要將一組操作組合在一起,即支持宏命令。
如:委派事件模型
3.解釋器模式
4.迭代器模式
5.中介者模式
5.1 動機
在面向對象的軟件設計與開發(fā)過程中,根據“單一職責原則”,我們應該盡量將對象細化,使其只負責或呈現單一的職責。
對于一個模塊,可能由很多對象構成,而且這些對象之間可能存在相互的引用,為了減少對象兩兩之間復雜的引用關系,使之成為一個松耦合的系統,我們需要使用中介者模式,這就是中介者模式的模式動機。
5.2 類圖
Mediator: 抽象中介者
ConcreteMediator: 具體中介者
Colleague: 抽象同事類
ConcreteColleague: 具體同事類
5.3 優(yōu)點
簡化了對象之間的交互。
將各同事解耦。
減少子類生成。
可以簡化各同事類的設計和實現。
5.4 缺點
在具體中介者類中包含了同事之間的交互細節(jié),可能會導致具體中介者類非常復雜,使得系統難以維護。
5.5 情景
系統中對象之間存在復雜的引用關系,產生的相互依賴關系結構混亂且難以理解。
一個對象由于引用了其他很多對象并且直接和這些對象通信,導致難以復用該對象。
想通過一個中間類來封裝多個類中的行為,而又不想生成太多的子類。可以通過引入中介者類來實現,在中介者中定義對象交互的公共行為,如果需要改變行為則可以增加新的中介者類。
6.備忘錄
6.1動機
在應用軟件的開發(fā)過程中,很多時候我們都需要記錄一個對象的內部狀態(tài)。
在具體實現過程中,為了允許用戶取消不確定的操作或從錯誤中恢復過來,需要實現備份點和撤銷機制,而要實現這些機制,必須事先將狀態(tài)信息保存在某處,這樣才能將對象恢復到它們原先的狀態(tài)。備忘錄模式是一種給我們的軟件提供后悔藥的機制,通過它可以使系統恢復到某一特定的歷史狀態(tài)。
6.2類圖
Originator: 原發(fā)器
Memento: 備忘錄
Caretaker: 負責人
6.3優(yōu)點
提供了一種狀態(tài)恢復的實現機制,使得用戶可以方便地回到一個特定的歷史步驟,當新的狀態(tài)無效或者存在問題時,可以使用先前存儲起來的備忘錄將狀態(tài)復原。
實現了信息的封裝,一個備忘錄對象是一種原發(fā)器對象的表示,不會被其他代碼改動,這種模式簡化了原發(fā)器對象,備忘錄只保存原發(fā)器的狀態(tài),采用堆棧來存儲備忘錄對象可以實現多次撤銷操作,可以通過在負責人中定義集合對象來存儲多個備忘錄。
6.4缺點
資源消耗過大,如果類的成員變量太多,就不可避免占用大量的內存,而且每保存一次對象的狀態(tài)都需要消耗內存資源,如果知道這一點大家就容易理解為什么一些提供了撤銷功能的軟件在運行時所需的內存和硬盤空間比較大了。
6.5情景
保存一個對象在某一個時刻的狀態(tài)或部分狀態(tài),這樣以后需要時它能夠恢復到先前的狀態(tài)。
如果用一個接口來讓其他對象得到這些狀態(tài),將會暴露對象的實現細節(jié)并破壞對象的封裝性,一個對象不希望外界直接訪問其內部狀態(tài),通過負責人可以間接訪問其內部狀態(tài)。
7.觀察者模式(Observer)
7.1動機
觀察者模式(Observer Pattern):定義對象間的一種一對多依賴關系,使得每當一個對象狀態(tài)發(fā)生改變時,其相關依賴對象皆得到通知并被自動更新。觀察者模式又叫做發(fā)布-訂閱(Publish/Subscribe)模式、模型-視圖(Model/View)模式、源-監(jiān)聽器(Source/Listener)模式或從屬者(Dependents)模式。觀察者模式是一種對象行為型模式。
7.2類圖
Subject: 目標
ConcreteSubject: 具體目標
Observer: 觀察者
ConcreteObserver: 具體觀察者
7.3優(yōu)點
觀察者模式可以實現表示層和數據邏輯層的分離,并定義了穩(wěn)定的消息更新傳遞機制,抽象了更新接口,使得可以有各種各樣不同的表示層作為具體觀察者角色。
觀察者模式在觀察目標和觀察者之間建立一個抽象的耦合。
觀察者模式支持廣播通信。觀察者模式符合“開閉原則”的要求。
7.4缺點
如果一個觀察目標對象有很多直接和間接的觀察者的話,將所有的觀察者都通知到會花費很多時間。
如果在觀察者和觀察目標之間有循環(huán)依賴的話,觀察目標會觸發(fā)它們之間進行循環(huán)調用,可能導致系統崩潰。
觀察者模式沒有相應的機制讓觀察者知道所觀察的目標對象是怎么發(fā)生變化的,而僅僅只是知道觀察目標發(fā)生了變化。
7.5情景
一個抽象模型有兩個方面,其中一個方面依賴于另一個方面。將這些方面封裝在獨立的對象中使它們可以各自獨立地改變和復用。
一個對象的改變將導致其他一個或多個對象也發(fā)生改變,而不知道具體有多少對象將發(fā)生改變,可以降低對象之間的耦合度。
一個對象必須通知其他對象,而并不知道這些對象是誰。需要在系統中創(chuàng)建一個觸發(fā)鏈,A對象的行為將影響B(tài)對象,B對象的行為將影響C對象……,可以使用觀察者模式創(chuàng)建一種鏈式觸發(fā)機制。
8.狀態(tài)模式(State)
8.1動機
狀態(tài)模式(State Pattern) :允許一個對象在其內部狀態(tài)改變時改變它的行為,對象看起來似乎修改了它的類。其別名為狀態(tài)對象(Objects for States),狀態(tài)模式是一種對象行為型模式。
8.2類圖
Context: 環(huán)境類
State: 抽象狀態(tài)類
ConcreteState: 具體狀態(tài)類
8.3優(yōu)點
封裝了轉換規(guī)則。
枚舉可能的狀態(tài),在枚舉狀態(tài)之前需要確定狀態(tài)種類。
將所有與某個狀態(tài)有關的行為放到一個類中,并且可以方便地增加新的狀態(tài),只需要改變對象狀態(tài)即可改變對象的行為。
允許狀態(tài)轉換邏輯與狀態(tài)對象合成一體,而不是某一個巨大的條件語句塊。可以讓多個環(huán)境對象共享一個狀態(tài)對象,從而減少系統中對象的個數。
8.4缺點
狀態(tài)模式的使用必然會增加系統類和對象的個數。
狀態(tài)模式的結構與實現都較為復雜,如果使用不當將導致程序結構和代碼的混亂。
狀態(tài)模式對“開閉原則”的支持并不太好,對于可以切換狀態(tài)的狀態(tài)模式,增加新的狀態(tài)類需要修改那些負責狀態(tài)轉換的源代碼,否則無法切換到新增狀態(tài);而且修改某個狀態(tài)類的行為也需修改對應類的源代碼。
8.5情景
對象的行為依賴于它的狀態(tài)(屬性)并且可以根據它的狀態(tài)改變而改變它的相關行為。
代碼中包含大量與對象狀態(tài)有關的條件語句,這些條件語句的出現,會導致代碼的可維護性和靈活性變差,不能方便地增加和刪除狀態(tài),使客戶類與類庫之間的耦合增強。在這些條件語句中包含了對象的行為,而且這些條件對應于對象的各種狀態(tài)。
9.策略模式(Strategy)
9.1動機
完成一項任務,往往可以有多種不同的方式,每一種方式稱為一個策略,我們可以根據環(huán)境或者條件的不同選擇不同的策略來完成該項任務。
9.2類圖
Context: 環(huán)境類
Strategy: 抽象策略類
ConcreteStrategy: 具體策略類
9.3優(yōu)點
策略模式提供了對“開閉原則”的完美支持,用戶可以在不修改原有系統的基礎上選擇算法或行為,也可以靈活地增加新的算法或行為。
策略模式提供了管理相關的算法族的辦法。
策略模式提供了可以替換繼承關系的辦法。
使用策略模式可以避免使用多重條件轉移語句。
9.4缺點
客戶端必須知道所有的策略類,并自行決定使用哪一個策略類。
策略模式將造成產生很多策略類,可以通過使用享元模式在一定程度上減少對象的數量。
9.5情景
如果在一個系統里面有許多類,它們之間的區(qū)別僅在于它們的行為,那么使用策略模式可以動態(tài)地讓一個對象在許多行為中選擇一種行為。
一個系統需要動態(tài)地在幾種算法中選擇一種。
如果一個對象有很多的行為,如果不用恰當的模式,這些行為就只好使用多重的條件選擇語句來實現。
不希望客戶端知道復雜的、與算法相關的數據結構,在具體策略類中封裝算法和相關的數據結構,提高算法的保密性與安全性。
如Java SE的容器布局管理
10.模板方法模式(Template Method)
10.1動機
模板方法模式是基于繼承的代碼復用基本技術,模板方法模式的結構和用法也是面向對象設計的核心之一。在模板方法模式中,可以將相同的代碼放在父類中,而將不同的方法實現放在不同的子類中。
10.2類圖
AbstractClass: 抽象類
ConcreteClass: 具體子類
10.3優(yōu)點
模板方法模式在一個類中形式化地定義算法,而由它的子類實現細節(jié)的處理。
模板方法模式是一種代碼復用的基本技術。
模板方法模式導致一種反向的控制結構,通過一個父類調用其子類的操作,通過對子類的擴展增加新的行為,符合“開閉原則”。
10.4缺點
每個不同的實現都需要定義一個子類,這會導致類的個數增加,系統更加龐大,設計也更加抽象,但是更加符合“單一職責原則”,使得類的內聚性得以提高。
10.5情景
一次性實現一個算法的不變的部分,并將可變的行為留給子類來實現。
各子類中公共的行為應被提取出來并集中到一個公共父類中以避免代碼重復。
對一些復雜的算法進行分割,將其算法中固定不變的部分設計為模板方法和父類具體方法,而一些可以改變的細節(jié)由其子類來實現。
控制子類的擴展。
11.訪問者模式(Visitor)
11.1動機
訪問者模式的目的是封裝一些施加于某種數據結構元素之上的操作,一旦這些操作需要修改的話,接受這個操作的數據結構可以保持不變。為不同類型的元素提供多種訪問操作方式,且可以在不修改原有系統的情況下增加新的操作方式,這就是訪問者模式的模式動機。
11.2類圖
11.3優(yōu)點
使得增加新的訪問操作變得很容易。
將有關元素對象的訪問行為集中到一個訪問者對象中,而不是分散到一個個的元素類中。
可以跨過類的等級結構訪問屬于不同的等級結構的元素類。讓用戶能夠在不修改現有類層次結構的情況下,定義該類層次結構的操作
11.4缺點
增加新的元素類很困難。在訪問者模式中,每增加一個新的元素類都意味著要在抽象訪問者角色中增加一個新的抽象操作,并在每一個具體訪問者類中增加相應的具體操作,違背了“開閉原則”的要求。
破壞封裝。訪問者模式要求訪問者對象訪問并調用每一個元素對象的操作,這意味著元素對象有時候必須暴露一些自己的內部操作和內部狀態(tài),否則無法供訪問者訪問。
11.5情景
一個對象結構包含很多類型的對象,希望對這些對象實施一些依賴其具體類型的操作。在訪問者中針對每一種具體的類型都提供了一個訪問操作,不同類型的對象可以有不同的訪問操作。
需要對一個對象結構中的對象進行很多不同的并且不相關的操作,而需要避免讓這些操作“污染”這些對象的類,也不希望在增加新操作時修改這些類。訪問者模式使得我們可以將相關的訪問操作集中起來定義在訪問者類中,對象結構可以被多個不同的訪問者類所使用,將對象本身與對象的訪問操作分離。
對象結構中對象對應的類很少改變,但經常需要在此對象結構上定義新的操作。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。