一、UML图
二、介绍
职责链模式(Chain Of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止。
职责链模式主要用于当一个请求有多种处理方式的时候,并且具体处理方式不确定的情况。
使用职责链模式的优点:
1.增强了系统的可扩展性。
2.使用职责链模式可以避免众多的if或者if-else语句。
3.使用职责链模式可以减小对象之间的耦合性。使得对象之间的联系减小。
4.可以根据需要自由组合工作流程。如工作流程发生变化,可以通过重新分配对象链便可适应新的工作流程。
5.责任的分担。每个类只需要处理自己该处理的工作(不该处理的传递给下一个对象完成),明确各类的责任范围,符合类的最小封装原则。
使用职责链模式的缺点:
1.使用职责链模式的时候会有多个处理者对象,但是实际使用的处理者对象却只有一个,这在某种程度讲是资源的浪费。
2.同时职责链的建立的合理性要靠客户端来保证,增加了程序的复杂性,也有可能由于职责链导致出错。
三、代码示范#include <iostream>
using namespace std;
class Handler
{
public:
Handler():handler(){}
virtual ~Handler()
{
cout << "Handler Construct" << endl;
}
void setSuccessor(Handler *successor)
{
handler = successor;
}
virtual void handleRequest(int request) = 0;
protected:
Handler *handler;
};
class ConcreteHandler1 : public Handler
{
public:
ConcreteHandler1():Handler()
{
cout << "ConcreteHandler1 Construct" << endl;
}
~ConcreteHandler1(){}
virtual void handleRequest(int request)
{
if (request >= 0 && request < 10)
{
cout << typeid(*this).name() << " could hand " << request << endl;
}
else if (handler != NULL)
{
handler->handleRequest(request);
}
}
};
class ConcreteHandler2 : public Handler
{
public:
ConcreteHandler2():Handler(){}
~ConcreteHandler2()
{
cout << "ConcreteHandler2 Construct" << endl;
}
virtual void handleRequest(int request)
{
if (request >= 10 && request < 20)
{
cout << typeid(*this).name() << " could hand " << request << endl;
}
else if (handler != NULL)
{
handler->handleRequest(request);
}
}
};
class ConcreteHandler3 : public Handler
{
public:
ConcreteHandler3():Handler(){}
~ConcreteHandler3()
{
cout << "ConcreteHandler3 Construct" << endl;
}
virtual void handleRequest(int request)
{
if (request >= 20 && request < 30)
{
cout << typeid(*this).name() << " could hand " << request << endl;
}
else if (handler != NULL)
{
handler->handleRequest(request);
}
}
};
int main()
{
Handler *h1 = new ConcreteHandler1();
Handler *h2 = new ConcreteHandler2();
Handler *h3 = new ConcreteHandler3();
h1->setSuccessor(h2);
h2->setSuccessor(h3);
h1->handleRequest(50);
delete h1;
delete h2;
delete h3;
getchar();
return 0;
}