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

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

作用

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

类视图

设计模式之责任链模式(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. 责任链中的每一个对象都有职责绝对是否对请求进行响应