一、简介
1.1 模式定义
避免请求发送者与接收者耦合在一起,让多个对象都可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理为止。由于英文翻译的不同,职责链模式又称为责任链模式,它是一种对象行为型模式。
1.2 适用场景
1)有多个对象可以处理同一个请求,具体哪个对象处理该请求有运行时刻自动确定。客户端只需要将请求提交到链上,无须关心请求的处理对象时谁以及它是如何处理的。
2)在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。请求的发送者与请求的处理者解耦,请求将沿着链进行传递,寻求相应的处理者。
3)可动态指定一组对象处理请求。客户端可以动态创建职责链来处理请求,还可以动态改变链中处理者之间的先后次序。
1.3 优点
1)降低耦合度:职责链模式使得无须知道是其他哪一个对象处理其请求。
对象仅需知道该请求会被处理即可,接收者和发送者都没有对方的明确信息,且链中的对象不需要知道链的结构,由客户端负责链的创建。
2)可简化对象的相互连接:请求处理对象仅需维持一个指向其后续者的引用,而不需维持它对所有的候选处理者的引用。
3)增强给对象指派职责的灵活性:在给对象分派职责时,职责链可以给我们带来更多的灵活性。可以通过在运行时对该链进行动态的增加一个请求的职责。
4)增加新的请求处理类很方便:在系统中增加一个新的具体请求处理者无须修改原有系统的代码,只需要在客户端重新建链即可,从这一点来看符合“开闭原则”的。
1.4 缺点
1)不能保证请求一定被接受:既然一个请求没有明确的接受者,那么久不能保证它一定会被处理请求可能一直到链的末端都得不到处理;一个请求也可能因职责链没有被正确配置而得不到处理。
2)对于比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定的影响,而且在进行代码调试时不太方便;如果建链不当,可能会造成循环调用,将导致系统陷入死循环。
二、示例
2.1 结构图
2.2 请求类LeaveRequest (请假条类)
public class LeaveRequest {
private String leaveName;
private int leaveDays;
public LeaveRequest(String leaveName, int leaveDays) {
this.leaveName = leaveName;
this.leaveDays = leaveDays;
}
public String getLeaveName() {
return leaveName;
}
public void setLeaveName(String leaveName) {
this.leaveName = leaveName;
}
public int getLeaveDays() {
return leaveDays;
}
public void setLeaveDays(int leaveDays) {
this.leaveDays = leaveDays;
}
}
2.3 抽象处理者Leader(领导类)
public abstract class Leader {
protected String name;
protected Leader successor;
public Leader(String name) {
this.name = name;
}
public void setSuccessor(Leader successor) {
this.successor = successor;
}
public abstract void handleRequest(LeaveRequest request);
}
2.4 具体处理者类Director(主任类)
public class Director extends Leader{
public Director(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest request) {
if (request.getLeaveDays() < 3) {
System.out.println("主任" + name + "审批员工" + request.getLeaveName() + "的请假条,请假天数为" + request.getLeaveDays() + "天");
} else {
if (this.successor != null) {
this.successor.handleRequest(request);
}
}
}
}
2.5 具体处理者Manager(经理类)
public class Manager extends Leader{
public Manager(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest request) {
if (request.getLeaveDays() < 10) {
System.out.println("经理" + name + "审批员工" + request.getLeaveName() + "的请假条,请假天数为" + request.getLeaveDays() + "天");
} else {
if (this.successor != null) {
this.successor.handleRequest(request);
}
}
}
}
2.6 具体处理者GeneraManager(总经理类)
public class GeneralManager extends Leader{
public GeneralManager(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest request) {
if (request.getLeaveDays() < 3) {
System.out.println("主任" + name + "审批员工" + request.getLeaveName() + "的请假条,请假天数为" + request.getLeaveDays() + "天");
} else {
System.out.println("莫非" + request.getLeaveName() + "想辞职,居然请假" + request.getLeaveDays() +"天");
}
}
}