动机:
在软件构建过程中,一个请求可能被多个对象处理,但是每个请求在运行时只能有一个接受者,如果显示指定,将必不可少的带来请求发送者与接受者的紧耦合。必须是请求的发送者不需要指定具体的接受者,让请求的接受者自己在运行时决定来处理请求,从而使两者解藕。
意图:
使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理为止。
- public abstract class BaseHandler
- {
- public BaseHandler(BaseHandler next)
- {
- this.next = next;
- }
- public virtual void HandleRequest(Request request)
- {
- if(next != null)
- {
- this.next.HandleRequest(request);
- }
- }
- public abstract bool CanHandleRequest();
- private BaseHandler next;
- public BaseHandler Next
- {
- get
- {
- return this.next;
- }
- set
- {
- this.next = value;
- }
- }
- }
- public class AHandler : BaseHandler
- {
- public AHandler(BaseHandler next) : base(next)
- {
- }
- public override void HandleRequest(Request request)
- {
- if(this.CanHandleRequest())
- {
- //处理
- }
- else
- {
- base.HandleRequest(request);
- }
- }
- public override bool CanHandleRequest()
- {
- return false;
- }
- }
- public class BHandler : BaseHandler
- {
- public BHandler(BaseHandler next) : base(next)
- {
- }
- public override void HandleRequest(Request request)
- {
- if(this.CanHandleRequest())
- {
- //处理
- }
- else
- {
- base.HandleRequest(request);
- }
- }
- public override bool CanHandleRequest()
- {
- return true;
- }
- }
- public class CHandler : BaseHandler
- {
- public CHandler(BaseHandler next) : base(next)
- {
- }
- public override void HandleRequest(Request request)
- {
- if(this.CanHandleRequest())
- {
- //处理
- }
- else
- {
- base.HandleRequest(request);
- }
- }
- public override bool CanHandleRequest()
- {
- return true;
- }
- }
- public class Request
- {
- }
- public class Sender
- {
- public void Process(BaseHandler handler)
- {
- Request request = new Request();
- handler.HandleRequest(request);
- //ArrayList list = new ArrayList();
- //list.Add(new AHandler());
- //list.Add(new BHandler());
- //list.Add(new CHandler());
- //foreach(BaseHandler handler in list)
- //{
- // if(handler.CanHandleRequest())
- // {
- // handler.HandleRequest(request);
- // }
- //}
- }
- }
- class Program
- {
- 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);
- }
- }
可以看到上面的代码,我们抽象出来BaseHandler类,作为处理类的基类,类里有一个虚方法HandleRequest,实现为将请求交个下一个Handler去处理,还有一个纯虚方法CanHandleRequest,用来判断是否当前Handler能否处理请求。next作为一个引用(指针)用来保存下一个处理器的地址。我们设计的思路就是构造一个像链表的处理器链,通过next指针连接起来。那么继承BaseHandler的A、B、C三个handler重写了CanHandleRequest和HandleRequest方法,CanHandleRequest方法用来判断当前Handler能否处理消息,HandleRequest方法首先判断当前Handler能否处理,如果能处理就自己处理,如果不能处理就交给下一个Handler处理。在Main函数里,我们实例化三个Handler,并且将他们链接起来。
要点:
Chain of Responsibility模式的应用场合在于一个请求可能有多个接受者,但是最后真正的接受者只有一个,只有这个时候请求发送者与接受者的耦合才可能出现变化脆弱的症状,职责链的目的就是将两者解藕,从而更好的应对变化。
应用了Chain of Resposibility模式后,对象的职责分派将更具有灵活性,我们可以在运行时动态添加/修改请求的处理职责,就是说我们可以动态的给职责链里插入Handler
如果请求传递到职责链的末尾仍得不到处理,应该有一个合理的缺省机制,这也是每一个接受对象的责任,而不是发出请求的对象的责任。
我们可以将职责链看作一个由很多小Handler组成的大Handler,他可以随时添加小的Handler,可以有默认处理的Handler,并且可以根据各种不同的条件来将消息给不同的小Handler处理。
但在windows消息循环中,没有用到职责链模式,因为消息循环需要快速的响应,并且,消息循环的消息种类太多,如果消息种类组成的职责链会相当的庞大,那么整个消息循环的机制会非常缓慢