责任链模式(Chain of Responsibility) 为解除请求的发送者和接收者之间的耦合,而使多个对象都有机会处理这个请求。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它。
示例
需求:模拟公司请假或者加薪的制度,请假天数不大于2天的由经理处理,请假天数大于2天不超过5天的请求由总监处理,请假大于5天或者请求加薪时由总经理处理。
首先定义处理请求行为的父类:
/**
* handler类
*/
public abstract class Manager {
protected String name;
public Manager(String name) {
this.name = name;
}
protected Manager superior;
public void setSuperior(Manager superior) {
this.superior = superior;
}
public abstract void requestApp(Request request);
}
经理:
/**
* 具体处理的类
*/
public class CommonManager extends Manager {
public CommonManager(String name) {
super(name);
}
//最先接受请求的经理对象,由其向后转发请求。请假天数不大于2天的由其处理。
@Override
public void requestApp(Request request) {
if (request.getRequestType().getValue().equals(RequestType.DAYOFF.getValue()) &&
request.getNumber() <= 2) {
System.out.println(name + ":" + request.getRequestContent() + request.getNumber() + "被批准");
} else if (superior != null) {
superior.requestApp(request);
}
}
}
总监:
public class Majordomo extends Manager {
public Majordomo(String name) {
super(name);
}
//总监对象,处理请假天数不超过5天的请求。
@Override
public void requestApp(Request request) {
if (request.getRequestType().getValue().equals(RequestType.DAYOFF.getValue()) &&
request.getNumber() <= 5) {
System.out.println(name + ":" + request.getRequestContent() + request.getNumber() + "被批准");
} else if (superior != null) {
superior.requestApp(request);
}
}
}
总经理:
public class GeneralManager extends Manager {
public GeneralManager(String name) {
super(name);
}
//请假大于5天或者请求加薪时由总经理处理
@Override
public void requestApp(Request request) {
if (request.getRequestType().getValue().equals(RequestType.DAYOFF.getValue())) {
System.out.println(name + ":" + request.getRequestContent() + request.getNumber() + "被批准");
} else if (request.getRequestType().getValue().equals(RequestType.ADDRAISE.getValue()) &&
request.getNumber() <= 500) {
System.out.println(name + ":" + request.getRequestContent() + request.getNumber() + "被批准");
} else if (request.getRequestType().getValue().equals(RequestType.ADDRAISE.getValue()) &&
request.getNumber() > 500) {
System.out.println(name + ":" + request.getRequestContent() + request.getNumber() + "被拒绝");
}
}
}
请求对象Request:
public class Request {
private RequestType requestType;
private int number;
private String requestContent;
public RequestType getRequestType() {
return requestType;
}
public void setRequestType(RequestType requestType) {
this.requestType = requestType;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public String getRequestContent() {
return requestContent;
}
public void setRequestContent(String requestContent) {
this.requestContent = requestContent;
}
}
public enum RequestType {
DAYOFF("请假"),
ADDRAISE("加薪");
private String value;
RequestType(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
运行测试:
@Test
public void ChainOfResponsibilityTest() {
CommonManager commonManager = new CommonManager("经理");
Majordomo majordomo = new Majordomo("总监");
GeneralManager generalManager = new GeneralManager("总经理");
commonManager.setSuperior(majordomo);
majordomo.setSuperior(generalManager);
Request request1 = new Request();
request1.setRequestContent("张三请假");
request1.setRequestType(RequestType.DAYOFF);
request1.setNumber(2);
commonManager.requestApp(request1);
Request request2 = new Request();
request2.setRequestContent("张三请假");
request2.setRequestType(RequestType.DAYOFF);
request2.setNumber(4);
commonManager.requestApp(request2);
Request request3 = new Request();
request3.setRequestContent("张三加薪");
request3.setRequestType(RequestType.ADDRAISE);
request3.setNumber(400);
commonManager.requestApp(request3);
Request request4 = new Request();
request4.setRequestContent("张三加薪");
request4.setRequestType(RequestType.ADDRAISE);
request4.setNumber(600);
commonManager.requestApp(request4);
//经理:张三请假2被批准
//总监:张三请假4被批准
//总经理:张三加薪400被批准
//总经理:张三加薪600被拒绝
}
责任链模式的好处:当客户提交一个请求时,请求时沿链传递直接有一个处理对象负责处理它。
这样做使得接收者和发送者都没有对方的明确信息,且链中的对象自己并不知道链的结构。结果是职责链可简化对象的相互连接。它们仅需保持一个指向其后继者的引用,而不需要保持它所有的候选接受者的引用。
我们需要注意的是:在设计具体的处理对象时,我们要确定请求是由当前处理对象出来或者是传递给后继者。
参考书籍:《大话设计模式》
本文地址:http://blog.csdn.net/ProdigalWang/article/details/78223472