標籤:
Chain Of Responsibility 職責鏈模式(行為型模式)
請求的寄件者與接受者
某些對象請求的接受者可能有多種多樣,變化無常……
動機(Motivation)
在軟體構建過程中,一個請求可能被多個對象處理,但是每個請求在運行時只能有一個接受者,如果顯示指定,將必不可少地帶來請求寄件者與接受者的緊耦合。
如何使請求的寄件者不需要指定具體的接受者?讓請求的接受者自己在運行時決定來處理請求,從而使兩者解耦。
意圖(Intent)
使多個對象都有機會處理請求,從而避免請求的寄件者和接受者之間的耦合關係。將這些對象連成一條鏈,並沿著這條鏈傳遞請求,直到有一個對象處理它為止。——《設計模式》GoF
範例程式碼
public abstract class BaseHandler { public abstract void HandleRequest(Request request); public abstract bool CanHandleRequest(Request request); } public class AHandler : BaseHandler { public override void HandleRequest(Request request) { //... } public override bool CanHandleRequest(Request request) { //... } } public class BHandler : BaseHandler { public override void HandleRequest(Request request) { //... } public override bool CanHandleRequest(Request request) { //... } } public class CHandler : BaseHandler { public override void HandleRequest(Request request) { //... } public override bool CanHandleRequest(Request request) { //... } } public class Request { //... } public class Sender { public void Process() { Request request=new Request(); //... List<BaseHandler> handlerList=new List<BaseHandler>(); handlerList.Add(new AHandler()); handlerList.Add(new BHandler()); handlerList.Add(new CHandler()); foreach (var handler in handlerList) { if (handler.CanHandleRequest(request)) { handler.HandleRequest(request); } } } }
如果我們不希望Sender中有這麼多的Handler的調用,可以通過指責鏈模式修改:
public abstract class BaseHandler { public BaseHandler(BaseHandler next) { this.Next = next; } public BaseHandler Next { get; set; } protected abstract bool CanHandleRequest(Request request); public virtual void HandleRequest(Request request) { if (this.Next != null) { this.Next.HandleRequest(request); } } } public class AHandler : BaseHandler { public AHandler(BaseHandler next) : base(next) { } public override void HandleRequest(Request request) { if (this.CanHandleRequest(request)) { //... } else { base.HandleRequest(request); } } protected override bool CanHandleRequest(Request request) { //... } } public class BHandler : BaseHandler { public BHandler(BaseHandler next) : base(next) { } public override void HandleRequest(Request request) { //... } protected override bool CanHandleRequest(Request request) { //... } } public class CHandler : BaseHandler { public CHandler(BaseHandler next) : base(next) { } public override void HandleRequest(Request request) { //... } protected override bool CanHandleRequest(Request request) { //... } } public class Request { //... } public class Sender { public void Process(BaseHandler handler) { Request request = new Request(); //... handler.HandleRequest(request); } }
用戶端調用:
static void Main(string[] args) { Sender sender=new Sender(); BaseHandler handler1 = new AHandler(null); BaseHandler handler2 = new BHandler(handler1); BaseHandler handler3 = new CHandler(handler2); sender.Process(handler3); Console.ReadKey(); }
結構(Structure)
一個典型的對象結構可能如所示:
Handler——定義一個處理請求的介面。(可選)實現後繼鏈。
ConcreteHandler——處理它所負責的請求。可訪問它的後繼者。如果可處理該請求,就處理之;否則將該請求轉寄給它的後繼者。
Client——向鏈上的具體處理者(ConcreteHandler)對象提交請求。
Chain Of Responsibility 模式的幾個要點
- Chain Of Responsibility 模式的應用場合在於“一個請求可能有多個接受者,但是最後真正的接受者只有一個”,只有這時候請求寄件者與接受者的耦合才有可能出現“變化脆弱”的癥狀,職責鏈的目的就是將兩者解耦,從而更好地應對變化。
- 應用了Chain Of Responsibility 模式後,對象的職責指派將更具靈活性。我們可以在運行時動態添加、修改請求的處理職責。
- 如果請求傳遞到職責鏈的末尾仍得不到處理,應該有一個處理的預設機制。這也是每一個接受對象的責任,而不是發出請求的對象的責任。
- 這種鏈傳遞的方式效率較低。
轉載請註明出處:
JesseLZJ
出處:http://jesselzj.cnblogs.com
設計模式19:Chain Of Responsibility 職責鏈模式(行為型模式)