人物:大鸟,小菜
事件:小菜在公司的试用期结束,马上要转正了,和部门经理沟通希望能加薪,经理没有权限于是报告给了总监,总监也说没有权限于是报告给了总经理,最后总经理驳回了审批,大鸟让小菜不要灰心,并就这一事件给小菜讲解了职责链模式
职责链模式:
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.职责链的好处
接受者和传递者没有对方明确的信息,且链中对象也不知道链的结构,结果是职责链可简化对象的互相连接,它们仅需保持一个指向后继者的引用,而且不需要保持所有候选者的引用,能够随时增加或者修改请求的结构,增强了对象指派职责的灵活性。