• 设计模式之责任链模式(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. 责任链中的每一个对象都有职责绝对是否对请求进行响应
  • 相关阅读:
    手脱ASPack2.12壳(练习)
    手脱UPX3.91壳(练习)
    如何在程序执行前插入可执行代码(算是吾爱的作业吧,活学活用)
    小米笔记本粉丝感恩狂欢趴【慎入!!】
    picpick截屏软件脱壳
    JAVA反序列化漏洞
    Java中的数据类型
    Java中常见的包
    Scrapy
    PHPstorm 函数时间注释的修改
  • 原文地址:https://www.cnblogs.com/chencarl/p/8762521.html
Copyright © 2020-2023  润新知