場景引入:在很多情況下可以處理某個請求的物件並不止乙個,例如大學裡的獎學金審批,學生在向班主任提交審批表之後首先是班主任簽字,然後交給學院負責人審核簽字,最後交由學工處負責人審批。在這個過程中獎學金申請表可以看成乙個請求物件,而不同級別的審批者都可以處理該請求物件,除了輔導員之外,學生不需要一一與其它審批者互動,只需等待結果就好。在審批的過程中如果有乙個審批者認為不符合條件,則終止請求,否則將請求遞交給下乙個審批者審批,最終有學工處負責人確定是否授予獎學金。
獎學金審批示意圖
在上圖中,班主任,學院負責人,學工處負責人都可以處理獎學金申請表,它們構成乙個處理申請表的鏈式結果,申請表沿著這條長鏈進行傳遞,這條鏈就稱為責任鏈。
定義:避免將乙個請求的傳送者與接受者耦合在一起,讓多個物件都有機會處理請求。將接收請求的物件連線成一條鏈,並且沿著這條鏈傳遞請求,直到有乙個物件能夠處理它為止。
由上圖可知,職責鏈包含兩個角色:
(1)handler(抽象處理者):它定義了乙個請求的介面,一般設計為抽象類,由於不同的具體處理者處理請求的方式不同,因此在其中定義了抽象請求處理方法。每乙個處理者的下家還是乙個處理者,故在抽象處理者中定義乙個抽象處理者型別的物件作為對下家的引用,通過該引用處理者可以連成一條鏈。
(2)concretehandle(具體處理者):它是抽象處理者的子類,可以處理使用者請求,在具體處理者類中實現了抽象處理者中定義的抽象請求處理方法,在處理請求之前要判斷,看是否有相應的處理許可權,如果可以處理請求就處理,否則就將它**給後繼者;在具體處理者中可以訪問鏈中的下乙個物件,以便請求的**。
職責鏈模式應用例項
1. 例項說明
某企業的scm(**鏈管理)系統中包含乙個採購審批子系統。該企業的採購審批是分級進行的,即根據採購金額的不同由不同層次的主管人員來審批。
主任可以審批5萬元以下的(不包括5萬元)的採購單,副董事長可以審批5萬元至10萬元(不包括10萬元)的採購單,董事長可以審批10萬至50萬(不包括50萬)的採購單,50萬及以上的採購單則需要開董事會討論決定,如下圖所示。
2. 例項類圖
3. 示例**
1package
designpatterns.chain;23
public
class
purchaserequest
1415
public
double
getamount()
1819
public
void setamount(double
amount)
2223
public
intgetnumber()
2627
public
void setnumber(int
number)
3031
public
string getpurpose()
3435
public
void
setpurpose(string purpose)
3839 }
1package
designpatterns.chain;23
public
abstract
class
4定義後繼物件
5protected string name; //
審批者姓名67
public
8super
();9
this.name =name;10}
1112
public
void
13this.successor =successor;14}
1516
public
abstract
void
processrequest(purchaserequest request);
1718 }
1package
designpatterns.chain;23
public
class director extends
4public
director(string name) 78
@override
9public
void
processrequest(purchaserequest request) else17}
18 }
1package
designpatterns.chain;23
public
class vicepresident extends45
public
vicepresident(string name) 89
@override
10public
void
processrequest(purchaserequest request) else18}
1920 }
1package
designpatterns.chain;23
public
class president extends
4public
president(string name) 78
@override
9public
void
processrequest(purchaserequest request) else
1718}19
20 }
1package
designpatterns.chain;23
public
class congress extends
4public
congress(string name) 78
@override
9public
void
processrequest(purchaserequest request)
1415 }
14. 執行結果package
designpatterns.chain;23
public
class
client
28 }
職責鏈模式優/缺點與使用環境
職責鏈模式優點
(1) 鏈中的物件不需要知道鏈的結構,由客戶端負責鏈的建立,降低了系統的耦合度
(2) 請求處理物件只需維持乙個指向其後繼者的引用
(3) 符合開閉原則
職責鏈模式缺點
(1) 由於乙個請求沒有明確的接收者,那麼不能保證它一定會被處理;乙個請求也可能因為職責鏈沒有正確配置而得到處理
(2) 如果鏈的建立不恰當,可能會導致迴圈呼叫,讓系統陷入死迴圈
職責鏈模式使用環境
(1) 有多個物件可以處理同乙個請求,客戶端只需將請求提交到鏈上,而無需關心請求的處理物件是誰以及它是如何處理的
(2) 在不明確指定接收者的情況下向多個物件中的乙個提交乙個請求
(3) 可動態指定一組物件處理請求
職責鏈模式
1.職責鏈 namespace dutychainpattern 用來處理請求 public abstract void transmitrequest int request 班主任 職責鏈上的乙個節點,在裡面進行判斷,看能否處理請求,不能則將請求轉移 public class classadvi...
職責鏈模式
軟體領域中的設計模式為開發人員提供了一種使用專家設計經驗的有效途徑。設計模式中運用了物件導向程式設計語言的重要特性 封裝 繼承 多型,真正領悟設計模式的精髓是可能乙個漫長的過程,需要大量實踐經驗的積累。最近看設計模式的書,對於每個模式,用c 寫了個小例子,加深一下理解。主要參考 大話設計模式 和 設...
職責鏈模式
劇情簡要 學習此模式,讓筆者聯想到自然界的生物鏈。打個比方 大魚吃小魚,小魚吃蝦公尺。河裡的小蝦公尺問大魚,你要不要吃我啊?大魚說 你太小了,吃了 沒吃,return 懶得吃!然後蝦公尺又問小魚 小螃蟹 小河馬同樣的問題。其實如果小蝦公尺這麼想自我了結的話,根本不用這麼費勁。這就開始了我們職責鏈模式...