设计模式十四:chain of responsibility(职责连模式)——对象行为型模式

行为模式
行为模式设计到算法和对象间职责的分配。行为模式不仅描述对象或类的模式,还描述他们之间的通信模式。这些模式刻画了在运行时难以跟踪的复杂控制流。他们将你的注意力从控制流转移到对象间的联系方式上来。
行为类模式使用继承机制在类间分派行为。
行为对象模式使用对象复合而不是继承。重点是对等的对象如何相互了解对方。

 


chain of responsibility(职责连模式)——对象行为型模式

 

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

 

2.动机
将提交请求的对象与处理的对象解耦。
给多个对象处理一个请求的机会,从而解耦发送者和接受者。该请求沿着对象链一直传递直至其中一个对象处理它。
从第一个对象开始,链中收到请求的对象要么亲自处理它,要么转发给链中的下一个候选者。递交请求的对象并不明确的知道哪一个对象将会处理它——我们说该请求有一个隐式的接受者。
要沿着链转发请求,并保证接受者为隐式的,每个在链上的对象都有一致的处理请求和访问链上的后继者的接口。

 

3.适用性
有多个的对象可以处理一个请求,哪个对象处理请求由运行时刻自动确定
你想在不明确制定接受者的情况下,向多个对象中的一个递交一个请求
可处理一个请求的对象集合应被动态制定

 

4.结构

参考:http://www.cnblogs.com/chengxingliang/archive/2011/10/08/2199128.html

 

 

5.参与者
handler
定义一个处理请求的接口
(可选)实现后继链
concreteHandler
处理它所负责的请求
可访问它的后继者
如果可处理该请求,就处理之,否则将传递给它的后继者
client
向链上的具体处理者对象递交请求

 

6.协作
当客户递交一个请求时,请求沿着链传递直至有一个concreteHandler对象负责处理它。

 

7.效果
优点:
1)降低耦合度
使一个对象无需知道是其他哪一个对象处理其请求。职责链可以简化对象的互相连接,仅需要保持一个指向其后继者的引用,而不需要保持它所有的候选接受者的引用。
2)增强了给对象指派职责的灵活性
当在对象中分派职责时,职责链给你更多的灵活性,可以在运行时刻对该链进行动态增加或者修改。可以将这种机制和静态的特例化处理对象的继承机制结合起来使用。
缺点:
不保证一定被接受

 

8.实现
要考虑的实现问题:
1)实现后继者链
a)定义新的链接,通常在handler中定义,但也可以由concreteHandler定义
b)使用已有的链接
2)连接后继者
如果没有已有的引用可定义一个链,那么你必须自己引入他们。这种情况下handler也需要维护后继链接。
3)表示请求
最简单的形式就是一个操作调用
也可以使用一个处理函数,这个函数以一个请求码为参数

 

9.代码示例

#include<iostream>
using namespace std;

class Request
{
    public:
    Request(string str, int n)
    {
        reName = str;
        prio = n;
    }
    int getPrio()
    {
        return prio;
    }
    string getReName()
    {
        return reName;
    }
    private:
    string reName;
    int prio;
};

class Handle
{
    public:
    string name;
    Handle *handle;
    Handle(string _n)
    {
        name = _n;
        handle = 0;
    }
    void setHandle(Handle *h)
    {
        handle = h;
    }
    virtual void exceRequest(Request *r){};
};

class employeeHandle:public Handle
{
    public:
    employeeHandle(string _n):Handle(_n){}
    void exceRequest(Request *r)
    {
        if(r->getPrio()>=3)
            cout<<name<<" execute "<<r->getReName()<<" prio = "<<r->getPrio()<<endl<<endl;
        else
        {
            cout<<"employee pass the request to the next->"<<endl;
            if(handle)
                handle->exceRequest(r);
            else
            {
                cout<<"execution failed"<<endl<<endl;
            }
        }    
    }
};

class managerHandle:public Handle
{
    public:
    managerHandle(string _n):Handle(_n){}
    void exceRequest(Request *r)
    {
        if(r->getPrio()>=2)
            cout<<name<<" execute "<<r->getReName()<<" prio = "<<r->getPrio()<<endl<<endl;
        else
        {
            cout<<"manager pass the request to the next->"<<endl;
            if(handle)
                handle->exceRequest(r);
            else
            {
                cout<<"execution failed"<<endl<<endl;
            }
        }    
    }
};

class bossHandle:public Handle
{
    public:
    bossHandle(string _n):Handle(_n){}
    void exceRequest(Request *r)
    {
        if(r->getPrio()>=1)
            cout<<name<<" execute "<<r->getReName()<<" prio = "<<r->getPrio()<<endl<<endl;
        else
        {
            cout<<"boss pass the request to the next->"<<endl;
            if(handle)
                handle->exceRequest(r);
            else
            {
                cout<<"execution failed"<<endl<<endl;
            }    
        }
            
    }
};

int main()
{
    
    Handle *employee = new employeeHandle("employee A");
    Handle *manager = new managerHandle("manager B");
    Handle *boss = new bossHandle("boss C");
    employee->setHandle(manager);
    manager->setHandle(boss);
    
    Request *req2 = new Request("WeiHua", 2);
    employee->exceRequest(req2);
    
    Request *req1 = new Request("Lilei", 1);
    employee->exceRequest(req1);
    
    Request *req0 = new Request("Hanmeimei", 0);
    employee->exceRequest(req0);
}

 

 

10.相关模式
经常和composite一起使用。这种情况下一个构建的父构建可作为他的后继

 

 

posted @ 2012-05-20 19:22  w0w0  阅读(238)  评论(0)    收藏  举报