《完美设计模式》之责任链模式

责任链模式:

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

主要解决:

职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。

关键代码:

Handler 里面聚合它自己,在 HanleRequest 里判断是否合适,如果没达到条件则向下传递,向谁传递之前 set 进去。

应用实例:

1、红楼梦中的”击鼓传花”。
2、JS 中的事件冒泡。
3、JAVA WEB 中 Apache Tomcat 对 Encoding 的处理,Struts2 的拦截器,jsp servlet 的 Filter。

优点:

1、降低耦合度。它将请求的发送者和接收者解耦。
2、简化了对象。使得对象不需要知道链的结构。
3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。
4、增加新的请求处理类很方便。

缺点:

1、不能保证请求一定被接收。
2、系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
3、可能不容易观察运行时的特征,有碍于除错。

使用场景:

1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。 2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
3、可动态指定一组对象处理请求。

实例:

接下来我们要编写一段代码,在工作中,请假是常有的事,比如某一天,你向你的上级请一天病假,你的经理一般都会给你审批,但是如果你一口气请三天,那么经理就没有权利给你审批了,经理就把你的申请报给上级,也就是你们的总监,总监根据你的实际情况来给你审批,如果你要请7天,估计会把你的申请递给老板,如果你在过分点,请个10几天,估计老板直接给你驳回,并狠狠教训你。在这里我们就能用责任链模式很好的实现这个过程。注意责任链模式,重点的是链这个字,怎么把你的经理,总监,老板链起来很重要。
代码中用的c++来实现
main函数:


    #include <iostream>
#include "handler.h"
using namespace std;

int main(int argc, char *argv[])
{
    //写请假条
    Request request;
    request.name = "leiyu";
    request.content = "ill";
    request.dayNum  = 1;

    //你的上级
    Manager *manager = new Manager;
    Majordomo *majordomo = new Majordomo;
    Boos *boos = new Boos;

    //整理上下级关系
    manager->setNextHander(majordomo);
    majordomo->setNextHander(boos);

    //我把请求先递给经理, 我不用去管他们内部的流程,我只管把请求递给我的直属上级
    int dayNumList[] = {1, 3, 7, 10};
    for (auto dayNum : dayNumList)
    {
        request.dayNum = dayNum;
        manager->handlerRequest(request);
    }

    return 0;
}

handler.h文件

    #ifndef HANDLER_H
    #define HANDLER_H
    #include <string>
    #include <iostream>
    using namespace std;

    #define PRINT_REQUES(request)\
        std::cout << "---------request----------" << std::endl;\
        std::cout << "    proposer:  " << request.name    << std::endl;\
        std::cout << "    content :  " << request.content << std::endl;\
        std::cout << "    day     :  " << request.dayNum  << std::endl;\
        std::cout << "--------------------------" << std::endl;
    /**
     * @brief The Request class
     * //请求类, 包括,申请人, 申请内容,和申请时间
     */
    class Request
    {
    public:
        Request(){}
        Request(std::string name, std::string content, int dayNum):
        name(name), content(content), dayNum(dayNum){}
        std::string name;     //请假人
        std::string content;  //请假内容
        int         dayNum;   //请假天数
    };

    //处理流程的结果,所有 有处理权限的人都要继承这个接口实现处理函数
    class Handler
    {
    private:
        Handler *nextHandler;   //下个处理人
        int level;             //当前处理人的权限等级


    public://这里
        Handler(int level):level(level), nextHandler(NULL){}
        void setNextHander(Handler *next)
        {
            this->nextHandler = next;
        }

        void handlerRequest(const Request &request)
        {
            //更具申请天数来判断执行权限
            if (this->level >= request.dayNum)
            {
                doHandler(request); //我有权利执行它
            }
            else
            {
                //我没权利,我就把申请传递给上级处理
                if (nextHandler != NULL)
                {
                    nextHandler->handlerRequest(request);
                }
                //否则,就视为不同意
                else
                {

                    PRINT_REQUES(request);
                    std::cout << "No disagree , eject" << endl;
                }
            }
        }

        /**
         * @brief doHandler 实际的处理
         * @param request
         */
        virtual void doHandler(const Request &request) = 0;

    };

    class Manager: public Handler
    {
    public:
        Manager(int level = 1):Handler(level){}

        void doHandler(const Request &request)
        {
            PRINT_REQUES(request);
            std::cout << "I`m Manager "
                      << "I agress this"
                      << std::endl;
        }
    };


    class  Majordomo: public Handler
    {
    public:
        Majordomo(int level = 3):Handler(level){}
        void doHandler(const Request &request)
        {
            PRINT_REQUES(request);
            std::cout << "I`m Maiordomo "
                      << "I agress this"
                      << std::endl;

        }
    };

    class Boos: public Handler
    {
    public:
        Boos(int level = 7):Handler(level){}
        void doHandler(const Request &request)
        {
            PRINT_REQUES(request);
            std::cout << "I`m Boos"
                      << "I agress this"
                      << std::endl;
        }

    };

    #endif // HANDLER_H

运行结果:

这里写图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值