假设有这么一个场景,学生们有个问题,需要去处理。有大多数情况下学生个人就能搞定这个通知,如果不行就让班长帮忙。班长也无能无力的时候就可以去找到辅导员,最终解决学生的问题。这中间就形成了一个职责链,当前级别无法处理问题时,就往上交付,知道解决为止。在程序中也可以通过责任链模式来把上述的场景展现出来。
UML图:
具体的代码实现如下:
/**
*代表职务或者是请求(问题)的等级
*/
public enum Status {
//辅导员,班长,学生
COUNSELOR, MONITOR, STUDENT
}
/**
* 抽象请求
*/
public abstract class AbstractRequest {
private String mContent;
public AbstractRequest(String content) {
mContent = content;
}
public String getContent() {
return mContent;
}
//获得请求级别
public abstract Enum getRequestStatus();
}
/**
* 不同级别的请求
*/
class RequestA extends AbstractRequest {
public RequestA(String content) {
super(content);
}
@Override
public Enum getRequestStatus() {
return Status.COUNSELOR;
}
}
class RequestB extends AbstractRequest {
public RequestB(String content) {
super(content);
}
@Override
public Enum getRequestStatus() {
return Status.MONITOR;
}
}
class RequestC extends AbstractRequest {
public RequestC(String content) {
super(content);
}
@Override
public Enum getRequestStatus() {
return Status.STUDENT;
}
}
/**
* 抽象处理者
*/
public abstract class AbstractHandler {
//下一个处理者,即上一级
private AbstractHandler nextHandler;
public final void handleRequest(AbstractRequest request) {
//请求的等级和处理者的等级相同,那当前处理者处理请求
if (getHandleStatus() == request.getRequestStatus()) {
handle(request);
} else {
//否则,交给下一个处理者处理
if (nextHandler != null) {
System.out.println(getHandleStatus() + " 处理不了 " + request.getContent());
nextHandler.handleRequest(request);
} else {
System.out.println("没人可以处理这个请求");
}
}
}
//setter
public void setNextHandler(AbstractHandler nextHandler) {
this.nextHandler = nextHandler;
}
//获取处理者等级
public abstract Enum getHandleStatus();
//处理请求,在子类实现
public abstract void handle(AbstractRequest request);
}
//辅导员
class Counselor extends AbstractHandler{
@Override
public Enum getHandleStatus() {
return Status.COUNSELOR;
}
@Override
public void handle(AbstractRequest request) {
System.out.println(getHandleStatus() + " 处理 " + request.getContent());
}
}
//班长
class Monitor extends AbstractHandler {
@Override
public Enum getHandleStatus() {
return Status.MONITOR;
}
@Override
public void handle(AbstractRequest request) {
System.out.println(getHandleStatus() + " 处理 " + request.getContent());
}
}
//学生
class Student extends AbstractHandler {
@Override
public Enum getHandleStatus() {
return Status.STUDENT;
}
@Override
public void handle(AbstractRequest request) {
System.out.println(getHandleStatus() + " 处理 " + request.getContent());
}
}
最后,可以通过发送请求来测试:
public class Client {
public static void main(String[] args) {
AbstractHandler counselor = new Counselor();
AbstractHandler monitor = new Monitor();
AbstractHandler student = new Student();
//设置责任链
student.setNextHandler(monitor);
monitor.setNextHandler(counselor);
// 创建三个不同等级的请求
AbstractRequest requestA = new RequestA("请求1");
AbstractRequest requestB = new RequestB("请求2");
AbstractRequest requestC = new RequestC("请求3");
//从学生开始处理
student.handleRequest(requestA);
student.handleRequest(requestB);
student.handleRequest(requestC);
}
}
结果:
STUDENT 处理不了 请求1
MONITOR 处理不了 请求1
COUNSELOR 处理 请求1
STUDENT 处理不了 请求2
MONITOR 处理 请求2
STUDENT 处理 请求3
一旦请求能够被责任链上的其中一个部分处理,那接下来就不会再传递下去了。这就是责任链模式的一个简单的实现方式。
责任链模式的优缺点
优点:可以将请求者与处理者的关系分离解耦,提高代码的灵活性。
缺点:每次都需要遍历责任链来找到合适的处理者,当责任链过长时,可能会影响程序的性能。