职责链模式
职责链可以是一条直线、一个环或者一个树形结构,最常见的职责链是直线型,即沿着一条单向的链传递请求。链上的每一个对象,都可以处理某种状态下的相同业务,客户端不用关心具体的处理内容,只要把被处理对象传递给链的第一个对象即可。
定义
避免将一个请求的发送者和接收者耦合在一起,让多个对象都有机会处理请求。将接受请求的对象连接成一个链,并且沿着这条链船队请求,直到有一个对象能够处理它为止。
结构
- Handler抽象处理者。它定义了一个处理请求的接口,一般为一个抽象类,它内部关联了一个本类对象,同时定义了处理请求的方法。
- ConcreteHandler具体处理者。它是抽象处理者的子类,接收处理请求的参数并进行分析,如果可以处理那么请求就不会往下发送,如果不能处理发送到下一个处理者。
实例
package responsibility;
public abstract class Controller {
protected String name;
protected Controller controller;
public Controller(String name) {
this.name = name;
}
public void setController(Controller controller) {
this.controller = controller;
}
public abstract void leavePermit(Leave leave);
}
package responsibility;
public class GroupLeader extends Controller {
public GroupLeader(String name) {
super(name);
}
@Override
public void leavePermit(Leave leave) {
if (leave.getDays() <= 1) {
System.out.println(this.name + "批准了" + leave.getName() + "的假期");
} else {
this.controller.leavePermit(leave);
}
}
}
package responsibility;
public class Director extends Controller {
public Director(String name) {
super(name);
}
@Override
public void leavePermit(Leave leave) {
System.out.println(this.name + "批准了" + leave.getName() + "的假期");
}
}
package responsibility;
public class Manager extends Controller {
public Manager(String name) {
super(name);
}
@Override
public void leavePermit(Leave leave) {
if (leave.getDays() < 3) {
System.out.println(this.name + "批准了" + leave.getName() + "的假期");
} else {
this.controller.leavePermit(leave);
}
}
}
package responsibility;
public class Leave {
private String name;
private Integer days;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getDays() {
return days;
}
public void setDays(Integer days) {
this.days = days;
}
public Leave(String name, Integer days) {
this.name = name;
this.days = days;
}
}
package responsibility;
public class Test {
public static void main(String[] args) {
Controller controller = new GroupLeader("张三");
controller.setController(new Manager("李四"));
controller.setController(new Director("王五"));
controller.leavePermit(new Leave("哈哈", 5));
}
}
优点
- 调用方只需要把参数传送到链上即可被处理,不需要知道具体的处理细节,实现了解耦。
- 职责的分配使用职责链具有更多的灵活性,添加新的职责只需要新增职责实现类就可以。
适用场景
- 有多个对象可以处理同一个请求的不同状态,具体处理者需要运行的时候才能知道。
- 不明确具体的处理者,客户端只需要向最开始的处理者发送请求。