十四、責任鏈模式(Chain of Responsibility)
1、定義
使多個物件都有機會處理請求,避免請求的傳送者和接受者之間的耦合關係。將這些物件連成一條鏈,並沿著這條鏈傳遞該請求,知道有一個物件來處理它為止。
2、類圖
Handler:定義職責的介面,通常在這裡定義處理請求的方法,可以在這裡實現後繼鏈。
ConcreteHandler:實現職責的類,在這個類裡面,實現對在它職責範圍內請求的處理,如果不處理,就繼續轉發請求給後繼者。
Client:職責鏈的客戶端,向鏈上的具體處理者物件提交請求,讓職責鏈負責處理。
3、呼叫順序
4、示例程式碼
5、 何時選用職責鏈模式
1、如果有多個物件可以處理同一個請求,但是具體由哪個物件來處理該請求,是執行時刻動態確定的
2、如果你想在不明確指定接收者的情況下,向多個物件中的一個提交一個請求的話,可以使用職責鏈模式
3、如果想要動態指定處理一個請求的物件集合,可以使用職責鏈模式,職責鏈模式能動態的構建職責鏈
十五、策略模式(Strategy)
1、定義
定義一系列的演算法,把它們一個個封裝起來,並且使它們可相互替換。本模式使得演算法可獨立於使用它的客戶而變化。
2、類圖
Strategy:策略介面,用來約束一系列具體的策略演算法。Context使用這個介面來呼叫具體的策略實現定義的演算法。ConcreteStrategy:具體的策略實現,也就是具體的演算法實現。
Context:上下文,負責和具體的策略類互動,通常上下文會持有一個真正的策略實現,上下文還可以讓具體的策略類來獲取上下文的資料,甚至讓具體的策略類來回撥上下文的方法。
3、呼叫順序
4、示例程式碼
/**
* 策略,定義演算法的介面
*/
public interface Strategy {
/**
* 某個演算法的介面,可以有傳入引數,也可以有返回值
*/
public void algorithmInterface();
}
複製程式碼
/**
* 實現具體的演算法
*/
public class ConcreteStrategyA implements Strategy {
public void algorithmInterface() {
//具體的演算法實現
}
}
複製程式碼
/**
* 實現具體的演算法
*/
public class ConcreteStrategyB implements Strategy {
public void algorithmInterface() {
//具體的演算法實現
}
}
複製程式碼
5、何時選用策略模式
1、出現有許多相關的類,僅僅是行為有差別的情況
2、出現同一個演算法,有很多不同的實現的情況
3、需要封裝演算法中,與演算法相關的資料的情況
十六、模板方法模式(Template Method)
1、定義
定義一個操作中的演算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以不改變一個演算法的結構即可重定義該演算法的某些特定步驟
2、類圖
AbstractClass:抽象類。用來定義演算法骨架和原語操作,具體的子類通過重定義這些原語操作來實現一個演算法的各個步驟。在這個類裡面,還可以提供演算法中通用的實現。ConcreteClass:具體實現類。用來實現演算法骨架中的某些步驟,完成跟特定子類相關的功能。
3、示例程式碼
十七、命令模式(Command)
1、定義
將一個請求封裝為一個物件,從而使你可用不同的請求對客戶進行引數化;對請求排隊或記錄請求日誌,以及支援可撤銷的操作。
2、類圖
Command:定義命令的介面,宣告執行的方法。
ConcreteCommand:命令介面實現物件,是“虛”的實現;通常會持有接收者,並呼叫接收者的功能來完成命令要執行的操作。
Receiver:接收者,真正執行命令的物件。任何類都可能成為一個接收者,只要它能夠實現命令要求實現的相應功能。
Invoker:要求命令物件執行請求,通常會持有命令物件,可以持有很多的命令物件。這個是客戶端真正觸發命令並要求命令執行相應操作的地方,也就是說相當於使用命令物件的入口。
Client:建立具體的命令物件,並且設定命令物件的接收者。注意這個不是我們常規意義上的客戶端,而是在組裝命令物件和接收者,或許,把這個Client稱為裝配者會更好理解,因為真正使用命令的客戶端是從Invoker來觸發執行。
3、呼叫順序
4、示例程式碼
真實示例
5、何時選用命令模式
1、如果需要抽象出需要執行的動作,並引數化這些物件,可以選用命令模式,把這些需要執行的動作抽象成為命令,然後實現命令的引數化配置
2、如果需要在不同的時刻指定、排列和執行請求,可以選用命令模式,把這些請求封裝成為命令物件,然後實現把請求佇列化
3、如果需要支援取消操作,可以選用命令模式,通過管理命令物件,能很容易的實現命令的恢復和重做的功能
4、如果需要支援當系統崩潰時,能把對系統的操作功能重新執行一遍,可以選用命令模式,把這些操作功能的請求封裝成命令物件,然後實現日誌命令,就可以在系統恢復回來後,通過日誌獲取命令列表,從而重新執行一遍功能
5、在需要事務的系統中,可以選用命令模式,命令模式提供了對事務進行建模的方法,命令模式有一個別名就是Transaction。
十八、觀察者模式(Observer)
1、定義
定義物件間的一種一對多的依賴關係,當一個物件的狀態發生改變時,所有依賴於它的物件都得到通知並自動更新。
2、類圖
Subject:目標物件,通常具有如下功能:
-
一個目標可以被多個觀察者觀察;
-
目標提供對觀察者註冊和退訂的維護;
-
當目標的狀態發生變化時,目標負責通知所有註冊的、有效的觀察者; Observer:定義觀察者的介面,提供目標通知時對應的更新方法,這個更新方法進行相應的業務處理,可以在這個方法裡面回撥目標物件,以獲取目標物件的資料。
ConcreteSubject:具體的目標實現物件,用來維護目標狀態,當目標物件的狀態發生改變時,通知所有註冊有效的觀察者,讓觀察者執行相應的處理。
ConcreteObserver:觀察者的具體實現物件,用來接收目標的通知,並進行相應的後續處理,比如更新自身的狀態以保持和目標的相應狀態一致。
3、呼叫順序
4、示例程式碼
十八、訪問者模式(Visitor)
1、定義
表示一個作用於某個物件結構中的各元素的操作。它使你可以在不改變各元素的類 的前提下定義作用於這些元素的新操作。
2、類圖
Visitor:訪問者介面,為所有的訪問者物件宣告一個visit方法,用來代表為物件結構新增的功能,理論上可以代表任意的功能。
ConcreteVisitor:具體的訪問者實現物件,實現要真正被新增到物件結構中的功能。
Element:抽象的元素物件,物件結構的頂層介面,定義接受訪問的操作。
ConcreteElement:具體元素物件,物件結構中具體的物件,也是被訪問的物件,通常會回撥訪問者的真實功能,同時開放自身的資料供訪問者使用。
ObjectStructure:物件結構,通常包含多個被訪問的物件,它可以遍歷這多個被訪問的物件,也可以讓訪問者訪問它的元素。可以是一個複合或是一個集合,如一個列表或無序集合。
3、呼叫順序
4、示例程式碼
5、何時選用訪問者模式
1、如果想對一個物件結構,實施一些依賴於物件結構中的具體類的操作,可以使用訪問者模式。
2、如果想對一個物件結構中的各個元素,進行很多不同的而且不相關的操作,為了避免這些操作使得類變得雜亂,可以使用訪問者模式,把這些操作分散到不同的訪問者物件中去,每個訪問者物件實現同一類功能。
3、如果物件結構很少變動,但是需要經常給物件結構中的元素物件定義新的操作,可以使用訪問者模式。
二十、狀態模式(State)
1、定義
允許一個物件在其內部狀態改變時改變它的行為。物件看起來似乎修改了它的類。
2、類圖
3、呼叫順序
4、示例程式碼
5、何時選用狀態模式
1、如果一個物件的行為取決於它的狀態,而且它必須在執行時刻根據狀態來改變它的行為
2、如果一個操作中含有龐大的多分支語句,而且這些分支依賴於該物件的狀態
二十一、直譯器模式(Interpreter)
1、定義
給定一個語言,定義它的文法的一種表示,並定義一個直譯器,這個直譯器使用該表示來解釋語言中的句子。
2、類圖
AbstractExpression:定義直譯器的介面,約定直譯器的解釋操作。TerminalExpression:終結符直譯器,用來實現語法規則中和終結符相關的操作,不再包含其它的直譯器,如果用組合模式來構建抽象語法樹的話,就相當於組合模式中的葉子物件,可以有多種終結符直譯器。
NonterminalExpression:非終結符直譯器,用來實現語法規則中非終結符相關的操作,通常一個直譯器對應一個語法規則,可以包含其它的直譯器,如果用組合模式來構建抽象語法樹的話,就相當於組合模式中的組合物件,可以有多種非終結符直譯器。
Context:上下文,通常包含各個直譯器需要的資料,或是公共的功能。
Client:客戶端,指的是使用直譯器的客戶端,通常在這裡去把按照語言的語法做的表示式,轉換成為使用直譯器物件描述的抽象語法樹,然後呼叫解釋操作。
3、呼叫順序
二十二、迭代器模式(Iterator)
1、定義
提供一種方法順序訪問一個聚合物件中各個元素,而又不需要暴露該物件的內部表示。
2、類圖
Iterator:迭代器介面。定義訪問和遍歷元素的介面。ConcreteIterator:具體的迭代器實現物件。實現對聚合物件的遍歷,並跟蹤遍歷時的當前位置。
Aggregate:聚合物件。定義建立相應迭代器物件的介面。
ConcreteAggregate:具體聚合物件。實現建立相應的迭代器物件。
3、示例程式碼
二十三、中介者模式(Mediator)
1、定義
用一箇中介物件來封裝一系列的物件互動。中介者使得各物件不需要顯示地相互引用,從而使其耦合鬆散,而且可以獨立的改變他們之間的互動。
2、類圖
Mediator:中介者介面。在裡面定義各個同事之間互動需要的方法,可以是公共的通訊方法,比如changed方法,大家都用,也可以是小範圍的互動方法。ConcreteMediator:具體中介者實現物件。它需要了解並維護各個同事物件,並負責具體的協調各同事物件的互動關係。
Colleague:同事類的定義,通常實現成為抽象類,主要負責約束同事物件的型別,並實現一些具體同事類之間的公共功能,比如:每個具體同事類都應該知道中介者物件,也就是具體同事類都會持有中介者物件,就可以定義到這個類裡面。
ConcreteColleague:具體的同事類,實現自己的業務,在需要與其它同事通訊的時候,就與持有的中介者通訊,中介者會負責與其它的同事互動。
3、呼叫順序
4、示例程式碼
5、何時選用中介者模式
如果一組物件之間的通訊方式比較複雜,導致相互依賴、結構混亂,可以採用中介者模式,把這些物件相互的互動管理起來,各個物件都只需要和中介者互動,從而使得各個物件鬆散耦合,結構也更清晰易懂。
如果一個物件引用很多的物件,並直接跟這些物件互動,導致難以複用該物件。可以採用中介者模式,把這個物件跟其它物件的互動封裝到中介者物件裡面,這個物件就只需要和中介者物件互動就可以了。
二十四、備忘錄模式(Memento)
1、定義
在不破壞封裝性的前提下,捕獲一個物件的內部狀態,並在該物件之外儲存這個狀態。這樣以後就可以將該物件恢復到原先儲存的狀態。
2、類圖
Memento:備忘錄。主要用來儲存原發器物件的內部狀態,但是具體需要儲存哪些資料是由原發器物件來決定的。另外備忘錄應該只能由原發器物件來訪問它內部的資料,原發器外部的物件不應該能訪問到備忘錄物件的內部資料。Originator:原發器。使用備忘錄來儲存某個時刻原發器自身的狀態,也可以使用備忘錄來恢復內部狀態。
Caretaker:備忘錄管理者,或者稱為備忘錄負責人。主要負責儲存備忘錄物件,但是不能對備忘錄物件的內容進行操作或檢查。