定義
責任鏈模式:使多個對象都有機會處理請求,從而避免了請求的發送者和接受者之間的耦合關係。將這些對象連成一條鏈,並沿着這條鏈傳遞該請求,直到有對象處理它爲止。
責任鏈模式(Chain of Responsibility) 是行爲型設計模式之一,它是一條鏈,鏈上每個節點都可以處理不同的內容,自己處理不了的交給下一個節點,直到最後一個節點。這樣的話,請求者不必直到這條鏈上誰可以處理,只要把請求往鏈裏塞就行了。
角色
職責鏈模式主要包含以下角色。
- 抽象處理者(Handler)角色:定義一個處理請求的接口,包含抽象處理方法和一個後繼連接。
- 具體處理者(Concrete Handler)角色:實現抽象處理者的處理方法,判斷能否處理本次請求,如果可以處理請求則處理,否則將該請求轉給它的後繼者。
- 客戶類(Client)角色:創建處理鏈,並向鏈頭的具體處理者對象提交請求,它不關心處理細節和請求的傳遞過程。
實現
責任鏈
抽象處理者
package factory.COR;
public abstract class Handler {
private Handler next;
public Handler getNext() {
return next;
}
public void setNext(Handler next) {
this.next = next;
}
public abstract void handleRequest(String request);
}
具體處理者1
package factory.COR;
public class ConcreteHandler1 extends Handler {
@Override
public void handleRequest(String request) {
if (request.equals("1")) {
System.out.println("處理者1處理。。。");
} else {
if (getNext() != null) {
getNext().handleRequest(request);
} else {
System.out.println("沒有人處理該請求。。。");
}
}
}
}
具體處理者2
package factory.COR;
public class ConcreteHandler2 extends Handler {
@Override
public void handleRequest(String request) {
if (request.equals("2")) {
System.out.println("處理者2處理。。。");
} else {
if (getNext() != null) {
getNext().handleRequest(request);
} else {
System.out.println("沒有人處理該請求。。。");
}
}
}
}
測試
package factory.COR;
public class Client {
public static void main(String[] args) {
Handler h1 = new ConcreteHandler1();
Handler h2 = new ConcreteHandler2();
h1.setNext(h2);
h1.handleRequest("2");
}
}
結果
優點
- 降低了對象之間的耦合度。該模式使得一個對象無須知道到底是哪一個對象處理其請求以及鏈的結構,發送者和接收者也無須擁有對方的明確信息。
- 增強了系統的可擴展性。可以根據需要增加新的請求處理類,滿足開閉原則。
- 增強了給對象指派職責的靈活性。當工作流程發生變化,可以動態地改變鏈內的成員或者調動它們的次序,也可動態地新增或者刪除責任。
- 責任鏈簡化了對象之間的連接。每個對象只需保持一個指向其後繼者的引用,不需保持其他所有處理者的引用,這避免了使用衆多的 if 或者 if···else 語句。
- 責任分擔。每個類只需要處理自己該處理的工作,不該處理的傳遞給下一個對象完成,明確各類的責任範圍,符合類的單一職責原則。
缺點
- 不能保證每個請求一定被處理。由於一個請求沒有明確的接收者,所以不能保證它一定會被處理,該請求可能一直傳到鏈的末端都得不到處理。
- 對比較長的職責鏈,請求的處理可能涉及多個處理對象,系統性能將受到一定影響。
- 職責鏈建立的合理性要靠客戶端來保證,增加了客戶端的複雜性,可能會由於職責鏈的錯誤設置而導致系統出錯,如可能會造成循環調用。