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

人物:大鸟,小菜

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


职责链模式:

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.职责链的好处

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

原文地址:https://www.cnblogs.com/wencheng9012/p/13451775.html