1.職責鏈模式的意圖
通過給多個對象處理請求的機會,以解除請求的發送者與接收者之間的耦合。將這個對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有一個對象處理它爲止。(客戶端不必事先知道對象集合中哪個對象可提供自己需要的服務)
2.職責鏈模式舉例
比如,班裏想申請一個教室舉辦元旦晚會,文藝委員不能自作主張使用某個教室,於是找到班長,班長要做的就是寫申請,向負責人員申請,負責人批准以後才能使用教室,這一步步的過程就像是一條鏈,從某一點開始執行,不能通過的話就向後走,知道找到某一點能解決了問題才終止。問題只要解決了就達到了目的,不用考慮中間有多少人蔘與過,也就是隻關心結果
此班學生的動機可以表示成如圖:
3.職責鏈模式解讀
角色:
- Client:客戶端
- Handler: 抽象處理者:定義出一個處理請求的接口。如果需要,接口可以定義出一個方法以設定和返回對下家的引用。這個角色通常由一個抽象類或接口實現
- ConcreteHandler:具體處理者:具體處理者接到請求後,可以選擇將請求處理掉,或者將請求傳給下家。由於具體處理者持有對下家的引用,因此,如果需要具體處理者可以訪問下家
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace 職責鏈模式
{
class Program
{
static void Main(string[] args)
{
//設置職責鏈上家與下家
Handler h1 = new ConcreteHandler1();
Handler h2 = new ConcreteHandler2();
Handler h3 = new ConcreteHandler3();
h1.SetSuccessor(h2);
h2.SetSuccessor(h3);
int[] requests = { 2, 5, 14, 22, 18, 3, 27, 20 };
foreach (int request in requests)
{
//循環給最小處理着提交請求,不同的數據由不同權限處理者處理
h1.HandleRequest(request);
}
Console.Read();
}
}
//Handler類,定義一個處理請示的接口
abstract class Handler
{
protected Handler successor;
//設置繼任者
public void SetSuccessor(Handler successor)
{
this.successor = successor;
}
//處理請求的抽象方法
public abstract void HandleRequest(int request);
}
//ConcreteHandler類,具體處理者類,處理它所負責的請求,可訪問它的後繼者,如果可處理該請求就處理它,否則就將該請求轉發給它的後繼者
//ConcreteHandler1類,當請求數在0到10之間則有權處理,否則轉到下一位
class ConcreteHandler1:Handler
{
public override void HandleRequest(int request)
{
if (request >= 0 && request < 10)
{
Console.WriteLine("{0}處理請求{1}", this.GetType ().Name , request);
}
else if (successor != null)
{
//轉移到下一位
successor.HandleRequest(request);
}
}
}
//ConcreteHandler2類,當請求數在10到20之間則有權處理,否則轉到下一位
class ConcreteHandler2 : Handler
{
public override void HandleRequest(int request)
{
if (request >= 10 && request < 20)
{
Console.WriteLine("{0}處理請求{1}", this.GetType().Name, request);
}
else if (successor != null)
{
successor.HandleRequest(request);
}
}
}
//ConcreteHandler3類,當請求數在20到30之間則有權處理,否則轉到下一位
class ConcreteHandler3 : Handler
{
public override void HandleRequest(int request)
{
if (request >= 20 && request < 30)
{
Console.WriteLine("{0}處理請求{1}", this.GetType().Name, request);
}
else if (successor != null)
{
successor.HandleRequest(request);
}
}
}
}
運行結果:
4.職責鏈模式優缺點
1)優點
- 降低耦合度
- 可簡化對象的相互連接
- 增強給對象指派職責的靈活性
- 方便增加新的類
2)缺點
- 請求到達末端也可能得不到處理
- 代碼調試時不太方便,可能會造成循環調用
- 有多個對象可以處理同一個請求,具體哪個對象處理該請求由運行時刻自動確定
- 在不明確指定接受者的情況下,向多個對象中的一個提交一個請求
- 可動態指定一組對象處理請求