职责链模式(Chain of Responsibility)

意图
十多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。
将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

应用场景
uu
类图

参与者
  • Handler
    定义一个处理请求的接口
    (可选)实现后继续
  • ConcreteHandler
    处理它所负责的请求接口
    可访问它的后继者
    如果处理该请求,就处理之。否者将该请求转发给它的后继者。
  • Client
    向链上的ConcreteHandler对象提交请求
代码
#include <iostream>
using namespace std;
class Handler
{
protected:
    Handler *successor;//后继者

public:
    //设置后继者
    void SetSuccessor(Handler *successor)
    {
        this->successor = successor;
    }
    //处理请求的抽象方法
    virtual void HandleRequest(int request) = 0;
};
//处理0-10的请求,否者交给后继者处理
class ConcreteHandler1:public Handler
{
public:
    void HandleRequest(int request)
    {
        //处理0-10的请求
        if(request>=0 && request<10)
        {
            cout<<"处理请求: "<<request<<endl;
        }
        //否者,交给后继者处理
        else if(successor != NULL)
        {
            successor->HandleRequest(request);
        }
    }
};
//处理10-20的请求,否者交给后继者处理
class ConcreteHandler2:public Handler
{
public:
    void HandleRequest(int request)
    {
        //处理10-20的请求
        if(request>=10 && request<20)
        {
            cout<<"处理请求: "<<request<<endl;
        }
        //否者,交给后继者处理
        else if(successor != NULL)
        {
            successor->HandleRequest(request);
        }
    }
};
//客户端代码,向连接上的具体处理者对象提交请求
int main()
{
    Handler *pH1 = new ConcreteHandler1();
    Handler *pH2 = new ConcreteHandler2();
    //设置职责连上家与下家
    pH1->SetSuccessor(pH2);

    int request[]={2, 4 , 19, 6 ,14};
    for(int i=0; i<5; i++)
    {
        pH1->HandleRequest(request[i]);
    }
}

思考(myself)
这样实现的职责连模式可能会降低程序的可扩展性。
比如:多个ConcreteHandler可以处理同样的请求,但是他们的优先级不同。程序完成后,他们的优先级变化了,或者有些ConcreteHandler死亡了。此时,代码就不易修改了。
改进: 可以用vector保存多个ConcreteHandler,通过优先级排序。然后遍历处理请求。
当一个ConcreteHandler死亡时,从vector中删除即可。
当优先级变化了,重新排序即可。
此时用优先队列可能更好一些。

具体:比如一个公司的经理,总经理,总监都可以处理加薪的请求。经理优先级更高。
某一天公司调整,又增加了一名项目经理,也可以处理加薪请求,且优先级比经理低,比总经理高。此时就不易对程序进行修改了。
如果用vector实现的话,只用将项目经理插到经理后面即可。




posted @ 2013-11-20 10:03  tanhaiyuan  阅读(168)  评论(0)    收藏  举报