职责链模式(Chain of Responsibility),使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连城一条链,并沿着这条链传递该请求,知道有一个对象处理它为止。
看着不太好理解,那么直接看例子:
在公司中,员工提交请求或者加薪请求,部门经理的权限是有限的,比如只能批准请求2天的请求,再多就需要向总监申请,超出总监权限范围的,就需要总经理去处理。这就可以用职责链模式来实现。
- 请求类
class Request {
private String type;
private int count;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
- 管理者抽象类
abstract class Manager {
// 姓名
String name;
// 上级
Manager superior;
Manager(String name) {
this.name = name;
}
// 设置上级
void setSuperior(Manager superior) {
this.superior = superior;
}
// 处理申请
abstract void dealRequest(Request request);
}
- 管理者实现类
// 普通经理类
class CommonManager extends Manager {
CommonManager(String name) {
super(name);
}
@Override
void dealRequest(Request request) {
if ("请假".equals(request.getType()) && request.getCount() <= 2) {
System.out.println("请假:" + request.getCount() + " 天,被普通经理:" + name + " 批准。");
} else {
if (superior != null) {
superior.dealRequest(request);
}
}
}
}
// 总监类
class MajorManager extends Manager {
MajorManager(String name) {
super(name);
}
@Override
void dealRequest(Request request) {
if ("请假".equals(request.getType()) && request.getCount() <= 5) {
System.out.println("请假:" + request.getCount() + " 天,被总监:" + name + " 批准。");
} else if ("加薪".equals(request.getType()) && request.getCount() <= 500) {
System.out.println("加薪:" + request.getCount() + " ,被总监:" + name + " 批准。");
} else {
if (superior != null) {
superior.dealRequest(request);
}
}
}
}
// 总经理类
class GeneralManager extends Manager {
GeneralManager(String name) {
super(name);
}
@Override
void dealRequest(Request request) {
if ("请假".equals(request.getType())) {
System.out.println("请假:" + request.getCount() + " 天,被总经理:" + name + " 批准。");
} else if ("加薪".equals(request.getType()) && request.getCount() <= 1000) {
System.out.println("加薪:" + request.getCount() + " ,被总经理:" + name + " 批准。");
} else {
System.out.println(request.getType() + ":" + request.getCount() + " ,被总经理:" + name + " 拒绝。");
}
}
}
- 主程序
class Test {
public static void main(String[] args) {
Manager commonManager = new CommonManager("王经理");
Manager majorManager = new MajorManager("张总监");
Manager generalManager = new GeneralManager("李总");
// 设置管理者的上级
commonManager.setSuperior(majorManager);
majorManager.setSuperior(generalManager);
Request request = new Request();
request.setType("请假");
request.setCount(2);
commonManager.dealRequest(request);
request = new Request();
request.setType("请假");
request.setCount(4);
commonManager.dealRequest(request);
request = new Request();
request.setType("请假");
request.setCount(6);
commonManager.dealRequest(request);
request = new Request();
request.setType("加薪");
request.setCount(500);
commonManager.dealRequest(request);
request = new Request();
request.setType("加薪");
request.setCount(1200);
commonManager.dealRequest(request);
}
}
运行结果:
请假:2 天,被普通经理:王经理 批准。
请假:4 天,被总监:张总监 批准。
请假:6 天,被总经理:李总 批准。
加薪:500 ,被总监:张总监 批准。
加薪:1200 ,被总经理:李总 拒绝。
由于直接领导是普通经理,所以每次请求只需提交给普通经理,当权限不够时,普通经理就会提交给上级去处理,通过调用superior.dealRequest(request)
方法传递给上级。
职责链的好处:
当客户提交一个请求时,请求是沿链传递直至有一个ConcreteHandler对象负责处理它。这就使得接收者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构。结果是职责链可简化对象的相互连接,它们仅需保持一个指向其后继者的引用,而不需保持它所有的候选者的引用。这样我们可以随时地增加或修改处理一个请求的结构。增强了给对象指派职责的灵活性。不过也要当心,一个请求极有可能到了链的末端都得不到处理,或者因为没有正确配置而得不到处理,这就需要事先考虑全面。