1、請求的發送者與接受者
1)某些對象請求的接受者可能多種多樣,變化無常......
2)請求發送者→請求接受者1,請求接受者2,請求接受者3,......
2、動機(Motivation)
1)在軟件構建過程當中,一個請求可能被多個對象處理,可是每一個請求在運行時只能有一個接受者,若是顯式指定,將必不可少地帶來請求發送者與接受者的緊耦合。
2)如何使請求的發送者不須要指定具體的接受者?讓請求的接受者本身在運行時決定來處理請求,從而使二者解耦。
3、意圖(Intent)
使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關係。將這些對象連成一條鏈,並沿着這條鏈傳遞請求,直到有一個對象處理它爲止。
——《設計模式》GoF
4、實例:
1)多種狀況的變化來處理一個對象,通常作法以下:
//請求接受者:抽象父類
public abstract class BaseHandler
{
public abstract void HandleRequest(Request request);
public abstract bool CanHandleRequest();
}設計模式
//請求接受者A
public class AHandler : BaseHandler
{
public override void HandleRequest(Request request)
{
}
public override bool CanHandleRequest()
{
}
}ide
//請求接受者B
public class BHandler : BaseHandler
{
public override void HandleRequest(Request request)
{
}
public override bool CanHandleRequest()
{
}
}this
//請求接受者C
public class CHandler : BaseHandler
{
public override void HandleRequest(Request request)
{
}
public override bool CanHandleRequest()
{
}
}設計
//請求的發送者
public class Sender
{
public void Process()
{
Request request = new Request();
List<BaseHandler> list = new List<BaseHandler>();
list.Add(new AHandler());
list.Add(new BHandler());
list.Add(new CHandler());
foreach (BaseHandler handler in list)
{
//若是可以處理這個請求,那麼就接受請求
if (handler.CanHandleRequest())
{
handler.HandleRequest(request);
}
}
}
}對象
public class Request
{
}繼承
2)職責鏈模式作法以下:重構獲得模式
//請求接受者:抽象父類
public abstract class BaseHandler
{
private BaseHandler next;
//構造器配合使用
public BaseHandler(BaseHandler next)
{
this.next = next;
}
public BaseHandler Next
{
get
{
return this.next;
}
set
{
this.next = value;
}
}
public virtual void HandleRequest(Request request)
{
if (this.next != null)
{
this.next.HandleRequest(request);
}
}
protected abstract bool CanHandleRequest(Request request);
}get
//請求接受者A
public class AHandler : BaseHandler
{
public AHandler(BaseHandler next) : base(next)
{
}
public override void HandleRequest(Request request)
{
if (this.CanHandleRequest(request))
{
//若是能處理本身處理
}
else
{
//不能處理交給基類
base.HandleRequset(request);
}
}
protected override bool CanHandleRequest(Request request)
{
if (.....)
{
return ture;
}
else
{
return false;
}
}
}it
//請求接受者B
public class BHandler : BaseHandler
{
public BHandler(BaseHandler next) : base(next)
{
}
public override void HandleRequest(Request request)
{
if (this.CanHandleRequest(request))
{
//若是能處理本身處理
}
else
{
//不能處理交給基類
base.HandleRequset(request);
}
}
protected override bool CanHandleRequest(Request request)
{
if (.....)
{
return ture;
}
else
{
return false;
}
}
}io
//請求接受者C
public class CHandler : BaseHandler
{
public CHandler(BaseHandler next) : base(next)
{
}
public override void HandleRequest(Request request)
{
if (this.CanHandleRequest(request))
{
//若是能處理本身處理
}
else
{
//不能處理交給基類
base.HandleRequset(request);
}
}
protected override bool CanHandleRequest(Request request)
{
if (.....)
{
return ture;
}
else
{
return false;
}
}
}class
//請求的發送者
public class Sender
{
//把請求交給一個對象就好了,無論誰來處理
public void Process(BaseHandler handler)
{
Request request = new Request();
hnadler.HandlerRequest(request);
}
}
//客戶
public class App
{
public static void Main()
{
Sender sender = new Sender();
BaseHandler handler1 = new Ahandler(null);
BaseHandler handler2 = new Bhandler(handler1);
BaseHandler handler3 = new Chandler(handler2);
BaseHandler handler4 = new Dhandler(null);
//運行時動態改變鏈表方向
handler3.Next = handler4;
handler4.Next = handler2;
sender.Process(handler3);
//方向:handler3-->handler4-->handler2-->handler1
//程序擴展直接繼承BaseHandler
//BaseHandler handler4 = new Dhandler(handler3);
//sender.Process(handler4);
//......
}
}
5、Chain Of Responsibility模式的幾個要點 1)Chain Of Responsibility模式的應用場合在於「一個請求可能有多個接受者,可是最後真正的接受者只有一個」,只有這時候請求發送者與接受者的耦合纔有可能出現「變化脆弱」的症狀,職責鏈的目的就是將兩者解耦,從而更好地應對變化。 2)應用了Chain Of Responsibility模式後,對象的職責分派將更具靈活性。咱們能夠在運行時動態添加/修改請求的處理職責。 3)若是請求傳遞到職責鏈的末尾仍得不處處理,應該有一個合理的缺省機制。這也是每個接受對象的責任,而不是發出請求的對象的責任。