欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

设计模式之责任链模式(Chain of Responsibility )

程序员文章站 2022-03-10 17:37:55
责任链的目的是通过特定的设计对请求者和接收者之间进行解耦,请求者调用操作的对象,接收者接收请求并执行相关操作,通过解耦请求者不需要关心接收者的接口,同时也可增强职责的灵活性,通过改变链内的成员或调用次序,允许动态新增或删除责任。 作用 责任链模式通过将多个对象连成链式模式,并沿着这个链传递命令或者请 ......

责任链的目的是通过特定的设计对请求者和接收者之间进行解耦,请求者调用操作的对象,接收者接收请求并执行相关操作,通过解耦请求者不需要关心接收者的接口,同时也可增强职责的灵活性,通过改变链内的成员或调用次序,允许动态新增或删除责任。

作用

责任链模式通过将多个对象连成链式模式,并沿着这个链传递命令或者请求,直到有对象处理它为止。

类视图

设计模式之责任链模式(Chain of Responsibility )

实现

我们还是取比较经典的员工请假的例子。员工为请假的请求者,接收者分别从项目经理、部门经理、公司经理这几个层级,员工向上进行请假操作,首先传递给项目经理,项目经理在处理时分为两种情况,如果项目经理人在公司,并且员工的请假天数满足请假的审批权限范围,则给予审批,反之则申请上级进行处理。

当然我们也可以制定自己的特殊规则,比如经理级别的接收者如果人不在,就不能向上进行请求,比如开可以增加请假的事由以供经理进行判断是否满足请假要求等,这些都可以根据实际情况进行扩充,感兴趣可以自己实现。

class DayOffRequest  
{  
public:  
    DayOffRequest(int hour)  
        :m_iHour(hour)  
    {}  
    int GetHour()  
    {  
        return m_iHour;  
    }  
private:  
    int  m_iHour;  
};  
  
class Manager  
{  
public:  
    virtual bool HandleRequest(DayOffRequest* request) = 0;   
};  
  
class PM : public  Manager   //Project manager项目经理  
{  
public:  
    PM(Manager* handler)  
    :m_Handler(handler)  
    {}  
    bool HandleRequest(DayOffRequest* request)  
    {  
        //在权责范围内给予批准
        if (request->GetHour() <= 2)  
        {  
            cout << "PM said : OK" << endl;  
            return true;  
        }
        else if (m_Handler) //请求上级
        {
            return m_Handler->HandleRequest(request);
        }
        else
        {
            //无法定夺
            cout <<"PM   said :no decide" << endl;  
            return false;
        }
    }  
private:  
    Manager* m_Handler;  
};  
  
class DM : public Manager //Department Manager部门经理  
{  
public:  
    DM(Manager* handler)  
        :m_handler(handler)  
    {}  
    bool HandleRequest(DayOffRequest* request)  
    {  
        if (m_Handler)
        {
            if(request->getHour() <=16)
            {
                cout <<"DM   said :OK" << endl;  
                return true;
            }
            else
                return m_Handler->HandleRequest(request);
        }
        else
        {   
            cout <<"DM   said :no decide" << endl;  
            return false;
        }
    }  
private:  
    Manager *m_handler;  
};  
  
class GM : public Manager //General Manager 总经理 
{  
public:  
    GM():m_handler(NULL)  {}
    bool IsInCompany()
    {
        return  static_cast<bool>(rand()%2) ;
    }
    bool HandleRequest(DayOffRequest* request)  
    {  
        if(IsInCompany())
        {
            cout <<"GM  said :OK" << endl; 
            return true;
        }
        else
        {
            cout <<"GM   said :try again latter" << endl; 
            return false;
        }
            
    }  
private:  
    Manager* m_handler;  
};
int  main()
{    
    Manager *general = new GM(); 
    Manager *department = new DM(general); //设置上级  
    Manager *project = new PM(department); //设置上级  
    
    DayOffRequest reqsta(2); //一个员工请假2小时
    project->DealWithRequest(&reqsta);  
     DayOffRequest reqstb(20); //另一个员工请假20小时
    project->DealWithRequest(&reqstb);   
    
    delete     project; 
    delete     department; 
    delete     general; 
}

责任链和观察者模式比较相像,都是进行命令和数据的传递,二者的关键区别是一个是有明确层级和先后关系(也可能不是那么明显),而一个是对象平等的,最通俗的例子就是网络中的DNS路由(链式)和广播模式(群发)的实现,这下大家就明白了吧;

当然也请注意链式结构的效率问题,对于层级最好还是加以控制。

应用场景

  1. 基于链式的请求和应答的结构;
  2. 发送者并不知道在链中的哪个对象会响应请求;
  3. 责任链中的每一个对象都有职责绝对是否对请求进行响应