• 大话设计模式读书笔记(职责链模式)


    人物:大鸟,小菜

    事件:小菜在公司的试用期结束,马上要转正了,和部门经理沟通希望能加薪,经理没有权限于是报告给了总监,总监也说没有权限于是报告给了总经理,最后总经理驳回了审批,大鸟让小菜不要灰心,并就这一事件给小菜讲解了职责链模式


    职责链模式:

    1.借小菜要求加薪的事件,让小菜将事件初步实现

    2.讲解了职责链模式,分别了解了职责链的概念,结构图,以及代码等

    3.用职责链再次实现小菜加薪事件(略)

    加薪请假代码初步实现

    Request类,申请请假或者加薪:

    @Data
    public class Request {
        /**
         * 申请类别
         */
        private String requestType;
        /**
         * 申请内容
         */
        private String requestContent;
        /**
         * 数量
         */
        private int number;
    
    }

    Manager类,管理者:

    @Slf4j
    public class Manager {
        protected String name;
    
        public Manager(String name) {
            this.name = name;
        }
    
        public void getResutl(String managerLevel, Request request) {
            if (managerLevel.equalsIgnoreCase("经理")) {
                if (request.getRequestType().equalsIgnoreCase("请假") && request.getNumber() <= 2) {
                    log.info("{}:{}数量{}被批准", name, request.getRequestContent(), request.getNumber());
                } else {
                    log.info("{}:{}数量{}我无权处理", name, request.getRequestContent(), request.getNumber());
                }
            } else if (managerLevel.equalsIgnoreCase("总监")) {
                if (request.getRequestType().equalsIgnoreCase("请假") && request.getNumber() <= 5) {
                    log.info("{}:{}数量{}被批准", name, request.getRequestContent(), request.getNumber());
                } else if (request.getRequestType().equalsIgnoreCase("加薪") && request.getNumber() <= 500) {
                    log.info("{}:{}数量{}被批准", name, request.getRequestContent(), request.getNumber());
                } else if (request.getRequestType().equalsIgnoreCase("加薪") && request.getNumber() >= 500) {
                    log.info("{}:{}数量{}再说吧", name, request.getRequestContent(), request.getNumber());
                }
            }
        }
    }

    客户端:

    public class RequestClient {
        public static void main(String[] args) {
            Manager jinli = new Manager("金利");
            Manager zongjian = new Manager("宗剑");
            Manager zhongjingli = new Manager("钟精励");
    
            Request request = new Request();
            request.setRequestType("加薪");
            request.setRequestContent("小菜请求加薪");
            request.setNumber(1000);
    
            jinli.getResutl("经理", request);
            zongjian.getResutl("总监", request);
            zhongjingli.getResutl("总经理", request);
    
            Request request2 = new Request();
            request2.setRequestType("请假");
            request2.setRequestContent("小菜请假");
            request2.setNumber(3);
    
            jinli.getResutl("经理", request2);
            zongjian.getResutl("总监", request2);
            zhongjingli.getResutl("总经理", request2);
        }
    }

    结果输出:

    金利:小菜请求加薪数量1000我无权处理
    宗剑:小菜请求加薪数量1000再说吧
    金利:小菜请假数量3我无权处理
    宗剑:小菜请假数量3被批准

    小菜:我知道自己写的不好,一个是管理者类中判断分支较多,导致方法较长,还有就是如果要增加leader,就还要修改逻辑,并且这个类职责太多,总之违背了单一职责原则和开放封闭原则等,但我就是不知道怎么去重构。

    职责链模式

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

    2.结构图:

    3.代码示例

    Handler类,定义一个处理请示的接口:

    public abstract class Handler {
        protected Handler successor;
    
        /**
         * 设置继任者
         *
         * @param successor
         */
        public void setSuccessor(Handler successor) {
            this.successor = successor;
        }
    
        /**
         * 处理请求的抽象方法
         *
         * @param request
         */
        public abstract void handleRequest(int request);
    }

    ConcreteHandler 1类,具体处理者类,处理它所负责的请求,可访问它的后继者,如果能处理请求就处理,不能处理就转发给它的后继者:

    @Slf4j
    public class ConcreteHandler1 extends Handler {
        @Override
        public void handleRequest(int request) {
            if (request >= 0 && request < 10) {
                log.info("处理请求{}", request);
            } else if (successor != null) {
                successor.handleRequest(request);
            }
        }
    }

    ConcreteHandler 2类,处理10到20之间的请求数,不能处理就转到下一位:

    @Slf4j
    public class ConcreteHandler2 extends Handler {
        @Override
        public void handleRequest(int request) {
            if (request >= 10 && request < 20) {
                log.info("处理请求{}", request);
            } else if (successor != null) {
                successor.handleRequest(request);
            }
        }
    }

    ConcreteHandler 2类,处理20到30之间的请求数,不能处理就转到下一位:

    @Slf4j
    public class ConcreteHandler3 extends Handler{
        @Override
        public void handleRequest(int request) {
            if (request >= 20 && request < 30) {
                log.info("处理请求{}", request);
            } else if (successor != null) {
                successor.handleRequest(request);
            }
        }
    }

    客户端:

    public class RequestClient {
        public static void main(String[] args) {
            Handler h1 = new ConcreteHandler1();
            Handler h2 = new ConcreteHandler2();
            Handler h3 = new ConcreteHandler3();
            h1.setSuccessor(h2);
            h2.setSuccessor(h3);
    
            int[] requests = {2, 5, 14, 22, 18, 3, 27, 20};
    
            for (int i : requests) {
                h1.handleRequest(i);
            }
        }
    }

    结果输出:

    处理请求2
    处理请求5
    处理请求14
    处理请求22
    处理请求18
    处理请求3
    处理请求27
    处理请求20

    4.职责链的好处

    接受者和传递者没有对方明确的信息,且链中对象也不知道链的结构,结果是职责链可简化对象的互相连接,它们仅需保持一个指向后继者的引用,而且不需要保持所有候选者的引用,能够随时增加或者修改请求的结构,增强了对象指派职责的灵活性。

  • 相关阅读:
    几个数之和----数组刷题
    单调栈刷题
    腾讯金融科技凉经
    mysql刷题
    链表类题目常用方法
    阿里云一面凉经
    腾讯TEG一面凉经
    腾讯软件开发-后台开发实习生-一面凉经
    剑指 Offer 19. 正则表达式匹配
    剑指 Offer 20. 表示数值的字符串
  • 原文地址:https://www.cnblogs.com/wencheng9012/p/13451775.html
Copyright © 2020-2023  润新知