Java設計模式之責任鏈模式詳解
責任鏈(Chain of Responsibility)模式的定義:為了避免請求發(fā)送者與多個請求處理者耦合在一起,于是將所有請求的處理者通過前一對象記住其下一個對象的引用而連成一條鏈;當有請求發(fā)生時,可將請求沿著這條鏈傳遞,直到有對象處理它為止。

責任鏈模式的結構
抽象處理者(Handler) 角色:定義一個處理請求的接口,包含抽象處理方法和一個后繼連接。
具體處理者(Concrete Handler)角色:實現抽象處理者的處理方法,判斷能否處理本次請求,如果可以處理請求則處理,否則將該請求轉給它的后繼者。
客戶類(Client) 角色:創(chuàng)建處理鏈,并向鏈頭的具體處理者對象提交請求,它不關心處理細節(jié)和請求的傳遞過程。
應用場景
- 多條件流程判斷權限控制。
- ERP系統(tǒng) 流程審批:總經理、人事經理、項目經理。
- Java過濾器的底層實現Filter
- 多個對象可以處理一個請求,但具體由哪個對象處理該請求在運行時自動確定。
- 可動態(tài)指定一組對象處理請求,或添加新的處理者。
- 需要在不明確指定請求處理者的情況下,向多個處理者中的一個提交請求。
優(yōu)缺點
優(yōu)點
- 降低了對象之間的耦合度。該模式使得一個對象無須知道到底是哪一個對象處理其請求以及鏈的結構,發(fā)送者和接收者也無須擁有對方的明確信息。
- 增強了系統(tǒng)的可擴展性??梢愿鶕枰黾有碌恼埱筇幚眍悾瑵M足開閉原則。
- 增強了給對象指派職責的靈活性。當工作流程發(fā)生變化,可以動態(tài)地改變鏈內的成員或者調動它們的次序,也可動態(tài)地新增或者刪除責任。
- 責任鏈簡化了對象之間的連接。每個對象只需保持一個指向其后繼者的引用,不需保持其他所有處理者的引用,這避免了使用眾多的
if或者if.else語句。 - 責任分擔。每個類只需要處理自己該處理的工作,不該處理的傳遞給下一個對象完成,明確各類的責任范圍,符合類的單一職責原則。
缺點
- 不能保證每個請求一定被處理。 由于一個請求沒有明確的接收者,所以不能保證它-定會被處理,該請求可能一直傳到鏈的末端都得不到處理。
- 對比較長的職責鏈,請求的處理可能涉及多個處理對象,系統(tǒng)性能將受到一定影響。
- 職責鏈建立的合理性要靠客戶端來保證,增加了客戶端的復雜性,可能會由于職責鏈的錯誤設置而導致系統(tǒng)出錯,如可能會造成循環(huán)調用。
代碼案例
請假條對象
public class LeaveRequest {
private String name;//姓名
private int num;//請假天數
private String content;//請假內容
public LeaveRequest(String name, int num, String content) {
this.name = name;
this.num = num;
this.content = content;
}
public String getName() {
return name;
}
public int getNum() {
return num;
}
public String getContent() {
return content;
}
}處理者抽象類
public abstract class Handler {
protected final static int NUM_ONE = 1;
protected final static int NUM_THREE = 3;
protected final static int NUM_SEVEN = 7;
//該領導處理的請假天數區(qū)間
private int numStart;
private int numEnd;
//領導上面還有領導
private Handler nextHandler;
//設置請假天數范圍 上不封頂
public Handler(int numStart) {
this.numStart = numStart;
}
//設置請假天數范圍
public Handler(int numStart, int numEnd) {
this.numStart = numStart;
this.numEnd = numEnd;
}
//設置上級領導
public void setNextHandler(Handler nextHandler){
this.nextHandler = nextHandler;
}
//提交請假條
public final void submit(LeaveRequest leave){
if(0 == this.numStart){
return;
}
//如果請假天數達到該領導者的處理要求
if(leave.getNum() >= this.numStart){
this.handleLeave(leave);
//如果還有上級 并且請假天數超過了當前領導的處理范圍
if(null != this.nextHandler && leave.getNum() > numEnd){
this.nextHandler.submit(leave);//繼續(xù)提交
} else {
System.out.println("流程結束");
}
}
}
//各級領導處理請假條方法
protected abstract void handleLeave(LeaveRequest leave);
}繼承抽象類實現責任鏈中各個類中的處理方法
public class Counselor extends Handler {
public Counselor() {
//輔導員 處理1-3天的請假
super(Handler.NUM_ONE, Handler.NUM_THREE);
}
@Override
protected void handleLeave(LeaveRequest leave) {
System.out.println(leave.getName() + "請假" + leave.getNum() + "天," + leave.getContent() + "。");
System.out.println("輔導員審批:同意。");
//也可以在這里設置下一個鏈路處理的handler
//setNextHandler(new Dean());
}
}
public class Dean extends Handler {
public Dean() {
//院長處理3-7天的請假
super(Handler.NUM_THREE, Handler.NUM_SEVEN);
}
@Override
protected void handleLeave(LeaveRequest leave) {
System.out.println(leave.getName() + "請假" + leave.getNum() + "天," + leave.getContent() + "。");
System.out.println("院長審批:同意。");
//也可以在這里設置下一個鏈路處理的handler
//setNextHandler(new CollegeSecretary ());
}
}
public class CollegeSecretary extends Handler {
public CollegeSecretary() {
//學院書記處理7天以上的請假
super(Handler.NUM_SEVEN);
}
@Override
protected void handleLeave(LeaveRequest leave) {
System.out.println(leave.getName() + "請假" + leave.getNum() + "天," + leave.getContent() + "。");
System.out.println("學院書記審批:同意。");
//也可以在這里設置下一個鏈路處理的handler
//setNextHandler(null); //最后一個
}
}測試類
public class TestClient {
public static void main(String[] args) {
//請假條來一張
LeaveRequest leave = new LeaveRequest("kaico",8,"身體不適");
//各級領導
Counselor counselor= new Counselor();
//如果前面handleLeave 方法中設置了下一個handler,這里就不需要了,直接提交申請就好了
Dean dean = new Dean();
CollegeSecretary collegeSecretary = new CollegeSecretary();
counselor.setNextHandler(dean);//輔導員的領導是院長
dean.setNextHandler(collegeSecretary);//院長的領導是學院書記
//提交申請
counselor.submit(leave);
}
}到此這篇關于Java設計模式之責任鏈模式詳解的文章就介紹到這了,更多相關Java責任鏈模式內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringBoot集成POI實現Excel導入導出的示例詳解
Apache?POI?是用Java編寫的免費開源的跨平臺的?Java?API,Apache?POI提供API給Java程序對Microsoft?Office格式檔案讀和寫的功能。本文主要介紹通過SpringBoot集成POI工具實現Excel的導入和導出功能,需要的可以參考一下2022-07-07
mybatis連接PGSQL中對于json和jsonb的處理方法
在使用PostgreSQL數據庫時,將表字段設置為jsonb格式可以存儲JSON數據,本文給大家介紹mybatis連接PGSQL中對于json和jsonb的處理方法,感興趣的朋友一起看看吧2024-11-11
SpringBoot實現WebSocket全雙工通信的項目實踐
本文主要介紹了SpringBoot實現WebSocket全雙工通信的項目實踐,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-05-05
java面試題——詳解HashMap和Hashtable 的區(qū)別
本篇文章主要介紹了java中HashMap和Hashtable的區(qū)別,具有一定的參考價值,有需要的可以了解一下。2016-11-11

