定义:
定义:
责任链模式是一种对象的行为模式【GOF95】。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配责任。实际的应用中责任链并不仅仅表现为链式结构,还有树型责任表等等。该模型的核心思想是分层处理客户请求,一方面对client端和sever端解耦(loose coupling),同时也为了server端解耦。目的是为了方便扩展功能。
类图如下所示:
client:负责提出业务请求,handler是服务端接口,concretehandler是对应的具体服务时序图如下所示:
第一个handler为抽象接口,后面的两个handler是对应的真正处理的server
应用:
首先看一个例子(图片来源http://blog.csdn.net/wyxhd2008/article/details/5604708)
这是一个典型的经典例子,请假这个事物,根据请假天数的区别,每一个管理者的权限都是不同的,例如10天以内部门经理批就可以了,不需要更高一级来核准,20天就需要总监批准
有一点要确认的是,员工所有的业务请求都要需要提交给他的上一级,(详细见上面的时序图)
例子:
#include <iostream>
#include <vector>
#include <ctime>
using namespace std;
class Base
{
Base *next; // 1. <span style="color:#ff6600;">"next" pointer in the base class</span>
public:
Base()
{
next = 0;
}
void setNext(Base *n)
{
next = n;
}
void add(Base *n)
{
if (next)
next->add(n);
else
next = n;
}
2. The "chain" method in the base class always delegates to the next obj
virtual void handle(int i)
{
next->handle(i);
}
};
class Handler1: public Base
{
public:
/*virtual*/void handle(int i)
{
if (rand() % 3)
{
// 3.Don't handle requests 3 times out of 4
cout << "H1 passsed " << i << " ";
Base::handle(i); // 3. Delegate to the base class
}
else
cout << "H1 handled " << i << " ";
}
};
class Handler2: public Base
{
public:
/*virtual*/void handle(int i)
{
if (rand() % 3)
{
cout << "H2 passsed " << i << " ";
Base::handle(i);
}
else
cout << "H2 handled " << i << " ";
}
};
class Handler3: public Base
{
public:
/*virtual*/void handle(int i)
{
if (rand() % 3)
{
cout << "H3 passsed " << i << " ";
Base::handle(i);
}
else
cout << "H3 handled " << i << " ";
}
};
int main()
{
srand(time(0));
Handler1 root;
Handler2 two;
Handler3 thr;
root.add(&two);
root.add(&thr);
thr.setNext(&root);
for (int i = 1; i < 10; i++)
{
root.handle(i);
cout << '\n';
}
}
>OUTPUT:
H1 passsed 1 H2 passsed 1 H3 passsed 1 H1 passsed 1 H2 handled 1
H1 handled 2
H1 handled 3
H1 passsed 4 H2 passsed 4 H3 handled 4
H1 passsed 5 H2 handled 5
H1 passsed 6 H2 passsed 6 H3 passsed 6 H1 handled 6
H1 passsed 7 H2 passsed 7 H3 passsed 7 H1 passsed 7 H2 handled 7
H1 handled 8
H1 passsed 9 H2 passsed 9 H3 handled 9
优缺点
优点无非就是降低了耦合、提高了灵活性。但是责任链模式可能会带来一些额外的性能损耗,因为它要从链子开头开始遍历。
不建议在阻塞情况下使用责任链模式,即使单线程。实际上建议每个handler都是一个独立的线程,每个thread维护一个由上一个节点给的command,这样可以分层、分线程对业务请求做处理,也就是说责任链是线程启发性的,在单个线程内用的话,可以考虑state模式(state 模式)