概念
又名责任链模式,为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链。当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止
结构
抽象处理者角色
定义一个处理请求的接口,包含抽象处理方法和一个后继连接对象
具体处理者角色
实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理则处理,不能处理则将该请求转给它的后继者
客户类角色
创建处理链,并向连头的具体处理者对象提交请求,不必关心具体处理细节和传递过程
示例
目标
员工进行请假,需要走流程,需要组长、经理同意。三天以下假期,组长可以做主;七天以下假期,经理可以做主,超过七天,不同意
请假条
package 设计模式.行为型模式.职责链模式;
/**
* 堆代码 duidaima.com
* 请假条
*/
public class LeaveRequest {
// 缘由
private String reason;
// 天数
private Integer days;
/**
* 构造函数
*/
public LeaveRequest(String reason, Integer days) {
this.reason = reason;
this.days = days;
}
public String getReason() {
return reason;
}
public Integer getDays() {
return days;
}
}
抽象处理者角色
package 设计模式.行为型模式.职责链模式;
/**
* 领导:抽象处理者角色
*/
public abstract class Leader {
// 后继处理者
private Leader nextLeader;
/**
* 设置后继处理者
*/
public void setNextLeader(Leader nextLeader) {
this.nextLeader = nextLeader;
}
/**
* 处理请假条
*/
public abstract void handle(LeaveRequest leaveRequest);
/**
* 交给后继处理者
*/
public final void submitNext(LeaveRequest leaveRequest) {
// 处理请假条
this.handle(leaveRequest);
// 若有下一级领导
if (this.nextLeader != null) {
this.nextLeader.submitNext(leaveRequest);
} else {
System.out.println("流程结束!");
}
}
}
具体处理者角色一
package 设计模式.行为型模式.职责链模式;
/**
* 组长:具体处理者
*/
public class GroupLeader extends Leader {
/**
* 处理请假条
*/
@Override
public void handle(LeaveRequest leaveRequest) {
// 大于等于3天的请假,交给下一级领导处理
if (leaveRequest.getDays() >= 3) {
System.out.println("组长:不在职责内,交由下一级");
return;
}
// 处理
System.out.println("组长:同意");
System.out.println("请假缘由:" + leaveRequest.getReason());
System.out.println("请假天数:" + leaveRequest.getDays());
}
}
具体处理者角色二
package 设计模式.行为型模式.职责链模式;
/**
* 经理:具体处理者
*/
public class Manager extends Leader {
/**
* 处理请假条
*/
@Override
public void handle(LeaveRequest leaveRequest) {
// 大于7天的请假,交给下一级领导处理
if (leaveRequest.getDays() > 7) {
System.out.println("经理:不同意");
return;
}
// 处理
System.out.println("经理:同意");
System.out.println("请假缘由:" + leaveRequest.getReason());
System.out.println("请假天数:" + leaveRequest.getDays());
}
}
客户类角色
package 设计模式.行为型模式.职责链模式;
/**
* 客户类角色
*/
public class Client {
public static void main(String[] args) {
// 创建请假条对象
LeaveRequest leaveRequest = new LeaveRequest("中暑", 8);
// 创建各级领导对象
GroupLeader groupLeader = new GroupLeader();
Manager manager = new Manager();
// 设置职责链
groupLeader.setNextLeader(manager);
// 执行流程
groupLeader.submitNext(leaveRequest);
}
}
优缺点
优点
1.降低了请求发送者和接收者之间的耦合度
2.增强了系统的可扩展性:可以根据需求增删请求处理类,而不会影响其他类,符合“开闭原则”
3.增强了给对象指派职责的灵活性:可以动态地改变链内成员的个数、执行顺序
4.简化了对象之间的连接:一个对象只需要保存一个后继处理者的引用即可,不需要保存其他所有处理者的引用
5.职责分担:每个类只需处理自己该处理的工作,不能处理的就交给后继处理者去处理,明确了各类的职责范围,符合类的单一职责原则
缺点
不能保证每个请求都一定被处理
当职责链比较长时,在性能方面会有一定的影响
职责链的合理性依赖客户端来保证,增加了客户端的复杂度。且若客户端有错误设置,会导致循环调用