设计模式小结-责任链模式
2017-12-28 本文已影响17人
r09er
责任链模式概述
现实中,向公司请假可能会走一系列的流程,其中请不同的天数也可能会由不同的人来审批,如果是3天以内的,你的直系上级领导应该就能批准,如果是3到7天,那么可能就要部门总经理批准,如果要请到30天,那么肯定就要更高的领导批准了,这个流程抽象出来,就形成了责任链模式.
责任链模式优缺点
优点
- 无需知道被哪个具体的对象实现,知道请求会被处理即可,调用链无需知道调用链的结构和顺序,能够降低耦合度
- 请求处理对象仅需维持一个指向其后继者的引用,而不需要维持它对所有的候选处理者的引用,可简化对象的相互连接。
- 能够在运行时对责任链进行动态的增加或修改,从而改变处理一个请求的职责
缺点
- 由于一个请求没有明确的接收者,那么就不能保证它一定会被处理,该请求可能一直到链的末端都得不到处理;一个请求也可能因职责链没有被正确配置而得不到处理。
- 如果建链不当,可能会造成循环调用,将导致系统陷入死循环。
适用场景
- 有多个对象可以处理同一个请求,具体哪个对象处理该请求待运行时刻再确定,客户端只需将请求提交到链上,而无须关心请求的处理对象是谁以及它是如何处理的。
- 可动态指定一组对象处理请求,客户端可以动态创建职责链来处理请求,还可以改变链中处理者之间的先后次序。
UML图

示例
一个假条审批模块:如果员工请假天数小于3天,主任可以审批该假条;如果员工请假天数大于等于3天,小于10天,经理可以审批;如果员工请假天数大于等于10天,小于30天,总经理可以审批;如果超过30天,总经理也不能审批,提示相应的拒绝信息。试用职责链模式设计该假条审批模块。
示例代码
请假实体类
public class LeaveRequest {
//请假天数
private int day;
//请假人名字
private String name;
public LeaveRequest(int day, String name) {
this.day = day;
this.name = name;
}
public int getDay() {
return day;
}
public void setDay(int day) {
this.day = day;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
抽象处理人
public abstract class Approver {
protected Approver nextApprover;
protected String processName;//处理人名字
public Approver(String processName) {
this.processName = processName;
}
public void setNextApprover(Approver nextApprover) {
this.nextApprover = nextApprover;
}
//处理请假的抽象方法
public abstract void processRequest(LeaveRequest leaveRequest);
}
具体处理人
public class Director extends Approver {
public Director(String processName) {
super(processName);
}
@Override
public void processRequest(LeaveRequest leaveRequest) {
if (leaveRequest.getDay() < 3) {
System.out.println(String.format("%s主任批准%s请%s天假", processName,leaveRequest.getName(),leaveRequest.getDay()));
} else {
//转发请求
nextApprover.processRequest(leaveRequest);
}
}
}
public class Manager extends Approver {
public Manager(String processName) {
super(processName);
}
@Override
public void processRequest(LeaveRequest leaveRequest) {
if (leaveRequest.getDay()<10) {
System.out.println(String.format("%s经理批准%s请%s天假",processName,leaveRequest.getName(),leaveRequest.getDay()));
}else{
this.nextApprover.processRequest(leaveRequest);
}
}
}
public class GeneralManager extends Approver {
public GeneralManager(String processName) {
super(processName);
}
@Override
public void processRequest(LeaveRequest leaveRequest) {
if (leaveRequest.getDay() < 30) {
System.out.println(String.format("%s总经理批准%s请%s天假",processName, leaveRequest.getName(), leaveRequest.getDay()));
} else {
System.out.println("拒绝提交超过30天的请假申请");
}
}
}
调用
public static void main(String[] args) {
LeaveRequest leaveRequest1 = new LeaveRequest(2,"哈哈");
LeaveRequest leaveRequest2 = new LeaveRequest(15,"呵呵");
LeaveRequest leaveRequest3 = new LeaveRequest(40,"嘿嘿");
Approver director = new Director("张三");
Approver manager = new Manager("李四");
Approver generalManager = new GeneralManager("王五");
director.setNextApprover(manager);
manager.setNextApprover(generalManager);
director.processRequest(leaveRequest1);
director.processRequest(leaveRequest2);
director.processRequest(leaveRequest3);
}