假設有這麼一個場景,學生們有個問題,需要去處理。有大多數情況下學生個人就能搞定這個通知,如果不行就讓班長幫忙。班長也無能無力的時候就可以去找到輔導員,最終解決學生的問題。這中間就形成了一個職責鏈,當前級別無法處理問題時,就往上交付,知道解決爲止。在程序中也可以通過責任鏈模式來把上述的場景展現出來。
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
一旦請求能夠被責任鏈上的其中一個部分處理,那接下來就不會再傳遞下去了。這就是責任鏈模式的一個簡單的實現方式。
責任鏈模式的優缺點
優點:可以將請求者與處理者的關係分離解耦,提高代碼的靈活性。
缺點:每次都需要遍歷責任鏈來找到合適的處理者,當責任鏈過長時,可能會影響程序的性能。