一、什么是職責鏈模式
????????職責鏈模式是一種行為型設計模式,它允許將請求沿著處理者的鏈進行傳遞,直到有一個處理者能夠處理它為止。換句話說,它將請求的發送者和接收者解耦,使得多個對象都有機會處理這個請求,從而避免了將請求直接發送給具體的處理者。
????????在職責鏈模式中,多個處理者對象形成一個鏈,客戶端將請求傳遞給鏈中的第一個處理者,由第一個處理者決定是自己處理請求,還是將請求傳遞給下一個處理者,直到請求被處理或者鏈末尾沒有處理者為止。
二、職責鏈模式的結構
- Handler(處理者):定義處理請求的接口,并且可以訪問下一個處理者。
- ConcreteHandler(具體處理者):實現了處理請求的具體邏輯,如果能夠處理該請求,則處理它,如果不能處理,則將請求傳遞給鏈中的下一個處理者。
- Client(客戶端):發起請求并傳遞給鏈中的第一個處理者。
三、職責鏈模式的優點
- 降低耦合性:請求發送者和請求接收者解耦,發送者無需知道具體處理者。
- 靈活性:可以靈活地組織處理者鏈,可以動態地改變鏈的結構。
- 簡化代碼:職責鏈模式可以避免多重條件語句,使代碼更簡潔。
四、職責鏈模式的缺點
- 鏈過長:如果鏈太長,可能會導致性能問題。
- 處理不當:如果沒有合適的處理者,可能會造成請求得不到處理。
五、案例講解:客服支持系統
????????假設我們有一個客服支持系統,客戶提交的問題根據其優先級需要經過不同層級的客服人員處理。優先級較低的問題由初級客服處理,優先級較高的問題由技術支持人員處理,如果問題依然沒有解決,那么會交給經理來處理。
????????我們可以使用職責鏈模式來處理這個場景。以下是完整的代碼實現。
六、代碼實現
1.問題設計(SupportTicket)
public class SupportTicket {private String description; // 問題描述private int priority; // 問題優先級,數值越大表示優先級越高public SupportTicket(String description, int priority) {this.description = description;this.priority = priority;}public String getDescription() {return description;}public int getPriority() {return priority;}
}
??SupportTicket
類表示客戶提交的問題,包含問題的描述和優先級。
2.抽象支持處理者(SupportHandler)
public abstract class SupportHandler {private SupportHandler nextHandler; // 下一個處理者// 設置下一個處理者public void setNextHandler(SupportHandler nextHandler){this.nextHandler = nextHandler;}// 獲取下一個處理者public SupportHandler getNextHandler(){return nextHandler;}// 處理請求的方法public abstract void handleTicket(SupportTicket ticket);
}
??SupportHandler
是職責鏈模式中的抽象處理者,它定義了處理請求的方法 handleTicket
,并且維護了一個指向下一個處理者的引用(nextHandler
)。
3.初級支持處理者(JuniorSupport)
public class JuniorSupport extends SupportHandler{@Overridepublic void handleTicket(SupportTicket ticket) {if(ticket.getPriority() <= 2){System.out.println("初級客服處理問題:"+ticket.getDescription());} else if (getNextHandler() != null) {getNextHandler().handleTicket(ticket); // 傳遞給下一個處理者} else {System.out.println("問題過大,需要匯報給總部處理!!!");}}
}
??JuniorSupport
是一個具體處理者類,當問題的優先級小于等于 2 時,它會處理該問題。如果問題優先級較高,它會將請求傳遞給下一個處理者。
4.技術支持處理者(TechSupport)
public class TechSupport extends SupportHandler{@Overridepublic void handleTicket(SupportTicket ticket) {if(ticket.getPriority() <= 4){System.out.println("技術員處理問題:"+ticket.getDescription());} else if (getNextHandler() != null) {getNextHandler().handleTicket(ticket); // 傳遞給下一個處理者} else {System.out.println("問題過大,需要匯報給總部處理!!!");}}
}
??TechSupport
處理優先級小于等于 4 的問題,其他問題會傳遞給下一個處理者。
5.經理支持處理者(ManagerSupport)
public class ManagerSupport extends SupportHandler{@Overridepublic void handleTicket(SupportTicket ticket) {if(ticket.getPriority() <= 10){System.out.println("經理處理問題:"+ticket.getDescription());} else if (getNextHandler() != null) {getNextHandler().handleTicket(ticket);} else {System.out.println("問題過大,需要匯報給總部處理!!!");}}
}
??ManagerSupport
處理優先級小于等于 10 的問題,其他問題會傳遞給下一個處理者,直到鏈的末尾。
6.測試類(TestChain)
public class TestChain {public static void main(String[] args) {// 問題聲明SupportTicket ticket1 = new SupportTicket("線路混亂", 1);SupportTicket ticket2 = new SupportTicket("服務器異常", 113);// 處理者聲明SupportHandler handler1 = new JuniorSupport();SupportHandler handler2 = new TechSupport();SupportHandler handler3 = new ManagerSupport();// 處理者鏈的組裝handler1.setNextHandler(handler2);handler2.setNextHandler(handler3);// 問題處理的傳遞handler1.handleTicket(ticket1);handler1.handleTicket(ticket2);}
}
????????在 TestChain
中,我們創建了三個處理者(JuniorSupport
、TechSupport
、ManagerSupport
),并將它們串聯成一個處理鏈。當請求傳遞給第一個處理者時,若它不能處理請求,就將請求交給下一個處理者,直到找到合適的處理者或者到達鏈的末尾。
7. 總結
????????職責鏈模式通過將請求沿著處理者鏈進行傳遞,使得每個處理者只關心自己能處理的請求,從而減少了發送者與接收者之間的耦合。職責鏈模式有助于系統的靈活擴展,因為我們可以在運行時動態地調整處理鏈結構。通過這種模式,能夠實現請求的逐層處理,直到有一個處理者能夠處理該請求為止。