目錄
- 定義與特點
- 結構與實作
- 模式的結構
- 模式的實作
- 應用場景
- 擴展:純、不純的職責鏈模式
在現實生活中,常常會出現這樣的事例:一個請求有多個物件可以處理,但每個物件的處理條件或權限不同,如找領匯出差報銷等,
在計算機軟硬體中也有相關例子,如總線網中資料報傳送、例外處理,所有這些,如果用責任鏈模式都能很好解決,
定義與特點
責任鏈(Chain of Responsibility)模式的定義:為了避免請求發送者與多個請求處理者耦合在一起,將所有請求的處理者通過前一物件記住其下一個物件的參考而連成一條鏈,當有請求發生時,可將請求沿著這條鏈傳遞,直到有物件處理它為止,
注意:責任鏈模式也叫職責鏈模式,
在責任鏈模式中,客戶只需要將請求發送到責任鏈上即可,無須關心請求的處理細節和請求的傳遞程序,所以責任鏈將請求的發送者和請求的處理者解耦了,
責任鏈模式是一種物件行為型模式,其主要優點如下:
- 降低了物件之間的耦合度:該模式使得一個物件無須知道到底是哪一個物件處理其請求以及鏈的結構,發送者和接收者也無須擁有對方的明確資訊,
- 增強了系統的可擴展性:可以根據需要增加新的請求處理類,滿足開閉原則,
- 增強了給物件指派職責的靈活性:當作業流程發生變化,可以動態地改變鏈內的成員或者調動它們的次序,也可動態地新增或者洗掉責任,
- 責任鏈簡化了物件之間的連接:每個物件只需保持一個指向其后繼者的參考,不需保持其他所有處理者的參考,這避免了使用眾多的 if 或者 if···else 陳述句,
- 責任分擔:每個類只需要處理自己該處理的作業,不該處理的傳遞給下一個物件完成,明確各類的責任范圍,符合類的單一職責原則,
其主要缺點如下:
- 不能保證每個請求一定被處理,由于一個請求沒有明確的接收者,所以不能保證它一定會被處理,該請求可能一直傳到鏈的末端都得不到處理,
- 對比較長的職責鏈,請求的處理可能涉及多個處理物件,系統性能將受到一定影響,
- 職責鏈建立的合理性要靠客戶端來保證,增加了客戶端的復雜性,可能會由于職責鏈的錯誤設定而導致系統出錯,如可能會造成回圈呼叫,
結構與實作
通常情況下,可以通過資料鏈表來實作職責鏈模式的資料結構,
模式的結構
職責鏈模式主要包含以下角色:
- 抽象處理者(Handler)角色:定義一個處理請求的介面,包含抽象處理方法和一個后繼連接,
- 具體處理者(Concrete Handler)角色:實作抽象處理者的處理方法,判斷能否處理本次請求,如果可以處理請求則處理,否則將該請求轉給它的后繼者,
- 客戶類(Client)角色:創建處理鏈,并向鏈頭的具體處理者物件提交請求,它不關心處理細節和請求的傳遞程序,
其結構圖如圖所示:

客戶端可按圖所示設定責任鏈:

模式的實作
職責鏈模式的實作代碼如下:
class Program
{
static void Main(string[] args)
{
//組裝責任鏈
Handler handler1=new ConcreteHandler1();
Handler handler2=new ConcreteHandler2();
handler1.SetNext(handler2);
//提交請求
handler1.HandleRequest("two");
Console.Read();
}
}
//抽象處理者角色
public abstract class Handler
{
private Handler next;
public void SetNext(Handler next)
{
this.next=next;
}
public Handler GetNext()
{
return next;
}
//處理請求的方法
public abstract void HandleRequest(String request);
}
//具體處理者角色1
public class ConcreteHandler1 : Handler
{
public override void HandleRequest(String request)
{
if(request.Equals("one"))
{
Console.WriteLine("具體處理者1負責處理該請求!");
}
else
{
if(GetNext()!=null)
{
GetNext().HandleRequest(request);
}
else
{
Console.WriteLine("沒有人處理該請求!");
}
}
}
}
//具體處理者角色2
public class ConcreteHandler2 : Handler
{
public override void HandleRequest(String request)
{
if(request.Equals("two"))
{
Console.WriteLine("具體處理者2負責處理該請求!");
}
else
{
if(GetNext()!=null)
{
GetNext().HandleRequest(request);
}
else
{
Console.WriteLine("沒有人處理該請求!");
}
}
}
}
程式運行結果如下:
具體處理者2負責處理該請求!
應用場景
前邊已經講述了關于責任鏈模式的結構與特點,下面介紹其應用場景,責任鏈模式通常在以下幾種情況使用:
- 有多個物件可以處理一個請求,哪個物件處理該請求由運行時刻自動確定,
- 可動態指定一組物件處理請求,或添加新的處理者,
- 在不明確指定請求處理者的情況下,向多個處理者中的一個提交請求,
擴展:純、不純的職責鏈模式
職責鏈模式存在以下兩種情況:
- 純的職責鏈模式:一個請求必須被某一個處理者物件所接收,且一個具體處理者對某個請求的處理只能采用以下兩種行為之一:自己處理(承擔責任);把責任推給下家處理,
- 不純的職責鏈模式:允許出現某一個具體處理者物件在承擔了請求的一部分責任后又將剩余的責任傳給下家的情況,且一個請求可以最終不被任何接收端物件所接收,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/1061.html
標籤:設計模式
上一篇:設計模式-組合模式
下一篇:行為型模式之狀態模式
