当前位置导航:炫浪网>>网络学院>>编程开发>>C++教程>>C++ Builder教程

职责链模式 X 简化连接 X 加薪流程

    职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递 该请求,知道有一个对象处理它为止[DP].

    在模式结构图中,结合上面的文字,不难想象:Client是和Handler相关的,它构造了Handler对象(main函数作为Client),所以它们之间是关联关系(实现实心箭头);Handler提供接口,ConcreteHandler提供具体的处理请求方法,所以它们之间是继承关系;此外,Handler需要提供SetSuccessor接口,好让每个ConcreteHandler知道自己的后继者。所以,ConcreteHandler和Handler之间有聚合关系:在每个Handler对象中必须提供一个成员,用以保存“后继处理者”的地址(作为protected成员,Handler保存ConcreteHandler;这类似于“雁群”聚合了“大雁”个体一样:在雁群类中,保存了大雁个体对象的地址,作为成员)。

    下面看看代码:

 #include <iostream>
using namespace std;
class Handler
{
protected:
Handler* m_Handler;
public:
Handler():m_Handler(NULL){}
virtual void setSuccessor(Handler* p)
{
m_Handler = p;
}
virtual void HandlerRequest(int request)=0;
};
class ConcreteHandler1 : public Handler
{
public:
void HandlerRequest(int request)
{
//满足条件则处理
if (request==10)
{
cout<<"ConcreteHandler1处理请求"<<endl;
}
else if (m_Handler!=NULL)
{
//让后继者处理
m_Handler->HandlerRequest(request);
}
else
cout<<"没人能处理了!"<<endl;
}
};
class ConcreteHandler2 : public Handler
{
public:
void HandlerRequest(int request)
{
//满足条件则处理
if (request==20)
{
cout<<"ConcreteHandler2处理请求"<<endl;
}
else if (m_Handler!=NULL)
{
//让后继者处理
m_Handler->HandlerRequest(request);
}
else
cout<<"没人能处理了!"<<endl;
}
};

void main()
{
Handler* h1 = new ConcreteHandler1();
Handler* h2 = new ConcreteHandler2();
h1->setSuccessor(h2);

int request=20;
h1->HandlerRequest(request);

request = 30;
h1->HandlerRequest(request);
};

    很简单吧?需要注意的是C++里面Handler的构造函数咯!如果不将m_Handler设为0的话,会运行出错(因为里面包含的是一个随机数,not NULL)。

    职责链的好处:每个对象只需要保持一个指向其后继者的引用,而不需要保持所有候选接收者的引用;降低了耦合度。我们可以随时增加或修改一个请求的结构,增强给对象指派职责的灵活性。

    需要担心的是:一个请求极可能到了链末端都没有得到处理,或者因为没有正确配置而得不到正确的处理[1]!

    我们来重构一下加薪流程的代码例子:程序员将请求提交给总监,然后总监提交给管理者……层层上报。管理者类自己聚合自己,也就是要保存一个自己上级的指针,它的子类:经理、总监,负责“申请请求”;这些子类和“申请”类之间是依赖关系:子类虚线实心箭头指向申请类,因为Request作为子类函数的参数。

    还是看看下面的实现代码吧:

    [1] 试想:A类和B类都处理request==10的情况,A对象在B的前面,那么B就得不到处理机会了;如果实际处理情况更加复杂一些:B处理A一些比A更严格的条件,那我在增添一个B类的时候,还要考虑:我当前设置是否合理?会不会消息还没有传递到B这里,就已经被A处理(拦截)了?这样的结果可不是我想要的呢!

相关内容
赞助商链接