1、定义:
职责连模式(Chain of Responsibility),使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将这个对象连成一条链,并沿着链传递该请求,直到由一个对象处理它为止。
|
2、UML
ConcreteHandler1、ConcreteHandler2 :具体处理者类,处理它所负责的请求,可访问它的后继者,如果可处理该请求,就处理之,否则就将该请求转发给他的后继者。
3、职责链的好处
- 关键在与当客户提交一个请求时,请求是沿着链传递直至由一个ConcreateHander对象负责处理它
- 请求者不用管哪个对象来处理,反正该请求会被处理就是了
- 接受者和发送者都没有对方的明确信息,且链中的对象自己也不知道链的结构。结果是职责链可简化对象的互相连接,它们仅需保持一个指向其后继者的引用,而不需要保持它所有的候选接受者的引用,大大降低了耦合度
- 我们可以随时的增加或修改一个请求的结构,增强了给对象指派职责的灵活性
4、实例:
请求类
package com.zcr.chain; //申请 public class Request { //申请类别 private String requestType; //申请内容 private String requestContent; //数量 private int number; public String getRequestType() { return requestType; } public void setRequestType(String requestType) { this.requestType = requestType; } public String getRequestContent() { return requestContent; } public void setRequestContent(String requestContent) { this.requestContent = requestContent; } public int getNumber() { return number; } public void setNumber(int number) { this.number = number; } }
package com.zcr.chain; //管理者 public abstract class Manager { protected String name; public Manager() { } //管理者的上级 protected Manager superior; public Manager(String name) { this.name = name; } //设置管理者的上级 public void SetSuperior(Manager superior) { this.superior = superior; } //申请请求 abstract public void RequestApplications(Request request); }
package com.zcr.chain; //经理 public class Majordomo extends Manager { public Majordomo(String name) { this.name = name; } @Override public void RequestApplications(Request request) { //经理所能有的权限就是可准许下属5天内的假期 if(request.getRequestType().equals("请假") && request.getNumber() <= 5) { System.out.println(name+":"+request.getRequestContent()+"数量"+request.getNumber()+"被批准"); } else { //其余的申请都需转到上级 if(null != superior) { superior.RequestApplications(request); } } } }
package com.zcr.chain; //总经理 public class GeneralManager extends Manager { public GeneralManager(String name) { this.name = name; } @Override public void RequestApplications(Request request) { //总经理允许任意时间假期 if(request.getRequestType().equals("请假")) { System.out.println(name+":"+request.getRequestContent()+"数量"+request.getNumber()+"被批准"); } else if(request.getRequestType().equals("加薪") && request.getNumber() <=500) { System.out.println(name+":"+request.getRequestContent()+"数量"+request.getNumber()+"被批准"); } else if(request.getRequestType().equals("加薪") && request.getNumber() >500) { System.out.println(name+":"+request.getRequestContent()+"数量"+request.getNumber()+"再说把"); } } }
package com.zcr.chain; //经理 public class CommonManager extends Manager { public CommonManager(String name) { this.name = name; } @Override public void RequestApplications(Request request) { //经理所能有的权限就是可准许下属两天内的假期 if(request.getRequestType().equals("请假") && request.getNumber() <= 2) { System.out.println(name+":"+request.getRequestContent()+"数量"+request.getNumber()+"被批准"); } else { //其余的申请都需转到上级 if(null != superior) { superior.RequestApplications(request); } } } }
package com.zcr.chain; public class ChainTest { public static void main(String[] args) { CommonManager jinli = new CommonManager("经理"); Majordomo zongjian = new Majordomo("总监"); GeneralManager zongjingli = new GeneralManager("总经理"); //设置上机,完全根据实际需求来更改设置 jinli.SetSuperior(zongjian); zongjian.SetSuperior(zongjingli); Request request = new Request(); request.setRequestType("请假"); request.setRequestContent("XX来请假"); request.setNumber(1); jinli.RequestApplications(request); //客户端的申请都是有“经理”发起,但实际上谁来决策由具体管理类来处理,客户端不知道 Request request2 = new Request(); request2.setRequestType("请假"); request2.setRequestContent("XX来请假"); request2.setNumber(4); jinli.RequestApplications(request2); Request request3 = new Request(); request3.setRequestType("加薪"); request3.setRequestContent("XX请求加薪"); request3.setNumber(500); jinli.RequestApplications(request3); Request request4 = new Request(); request4.setRequestType("加薪"); request4.setRequestContent("XX请求加薪"); request4.setNumber(1000); jinli.RequestApplications(request4); } }
5、结果:
6、书籍推荐
《大话设计模式》。上面的例子来自该书的改变,该书通过小菜和大鸟两人在生活中遇到的事情引出设计模式来解决问题,富有趣味性。读起来没那么枯燥无味。