常用设计模式——职责链模式
目錄
前言
1.職責鏈模式的定義與特點
2.職責鏈模式的結構與實現
2.1?模式的結構
2.2?模式的實現
前言
????????在現實生活中,一個事件需要經過多個對象處理是很常見的場景。例如,采購審批流程、請假流程等。公司員工請假,可批假的領導有部門負責人、副總經理、總經理等,但每個領導能批準的天數不同,員工必須根據需要請假的天數去找不同的領導簽名,也就是說員工必須記住每個領導的姓名、電話和地址等信息,這無疑增加了難度。
????????在計算機軟硬件中也有相關例子,如總線網中數據報傳送,每臺計算機根據目標地址是否同自己的地址相同來決定是否接收;還有異常處理中,處理程序根據異常的類型決定自己是否處理該異常;還有 Struts2的攔截器、JSP和 Servlet 的 Filter 等,所有這些,都可以考慮使用職責鏈模式來實現。
1.職責鏈模式的定義與特點
職責鏈(Chain of Responsibility)模式的定義:為了避免請求發送者與多個請求處理者耦合在一起,于是將所有請求的處理者通過前一對象記住其下一個對象的引用而連成一條鏈;當有請求發生時,可將請求沿著這條鏈傳遞,直到有對象處理它為止。(職責鏈模式也稱為責任鏈模式)
????????在職責鏈模式中,客戶只需要將請求發送到職責鏈上即可,無須關心請求的處理細節和請求的傳遞過程,請求會自動進行傳遞。所以職責鏈將請求的發送者和請求的處理者解耦了。
職責鏈模式主要優點如下:
降低了對象之間的耦合度。該模式使得一個對象無須知道到底是哪一個對象處理其請求以及鏈的結構,發送者和接收者也無須擁有對方的明確信息。
增強了系統的可擴展性。可以根據需要增加新的請求處理類,滿足開閉原則。
增強了給對象指派職責的靈活性。當工作流程發生變化,可以動態地改變鏈內的成員或者調動它們的次序,也可動態地新增或者刪除責任。
職責鏈簡化了對象之間的連接。每個對象只需保持一個指向其后繼者的引用,不需保持其他所有處理者的引用,這避免了使用眾多的 if 或者 if···else 語句。
責任分擔。每個類只需要處理自己該處理的工作,不該處理的傳遞給下一個對象完成,明確各類的責任范圍,符合類的單一職責原則。
其主要缺點如下:
不能保證每個請求一定被處理。由于一個請求沒有明確的接收者,所以不能保證它一定會被處理,該請求可能一直傳到鏈的末端都得不到處理。
對比較長的職責鏈,請求的處理可能涉及多個處理對象,系統性能將受到一定影響。
職責鏈建立的合理性要靠客戶端來保證,增加了客戶端的復雜性,可能會由于職責鏈的錯誤設置而導致系統出錯,如可能會造成循環調用。
2.職責鏈模式的結構與實現
通常情況下,可以通過數據鏈表來實現職責鏈模式的數據結構。
2.1?模式的結構
職責鏈模式主要包含以下角色。
抽象處理者(Handler)角色:定義一個處理請求的接口,包含抽象處理方法和一個后繼連接。
具體處理者(Concrete Handler)角色:實現抽象處理者的處理方法,判斷能否處理本次請求,如果可以處理請求則處理,否則將該請求轉給它的后繼者。
客戶類(Client)角色:創建處理鏈,并向鏈頭的具體處理者對象提交請求,它不關心處理細節和請求的傳遞過程。
????????責任鏈模式的本質是解耦請求與處理,讓請求在處理鏈中能進行傳遞與被處理;理解責任鏈模式應當理解其模式,而不是其具體實現。責任鏈模式的獨到之處是將其節點處理者組合成了鏈式結構,并允許節點自身決定是否進行請求處理或轉發,相當于讓請求流動起來。
圖1 責任鏈模式的結構圖
2.2?模式的實現
職責鏈模式的實現代碼如下:
public class ChainOfResponsibilityPattern {public static void main(String[] args) {//組裝責任鏈Handler handler1 = new ConcreteHandler1();Handler handler2 = new ConcreteHandler2();handler1.setNext(handler2);//提交請求handler1.handleRequest("two");} } //抽象處理者角色 abstract class Handler {private Handler next;public void setNext(Handler next) {this.next = next;}public Handler getNext() {return next;}//處理請求的方法public abstract void handleRequest(String request); } //具體處理者角色1 class ConcreteHandler1 extends Handler {public void handleRequest(String request) {if (request.equals("one")) {System.out.println("具體處理者1負責處理該請求!");} else {if (getNext() != null) {getNext().handleRequest(request);} else {System.out.println("沒有人處理該請求!");}}} } //具體處理者角色2 class ConcreteHandler2 extends Handler {public void handleRequest(String request) {if (request.equals("two")) {System.out.println("具體處理者2負責處理該請求!");} else {if (getNext() != null) {getNext().handleRequest(request);} else {System.out.println("沒有人處理該請求!");}}} }程序運行結果如下:
具體處理者2負責處理該請求!????????在上面代碼中,我們把消息硬編碼為 String 類型,而在真實業務中,消息是具備多樣性的,可以是 int、String 或者自定義類型。因此,在上面代碼的基礎上,可以對消息類型進行抽象 Request,增強了消息的兼容性。
ps:各位看官,看完就點個贊吧,多謝各位看官!
總結
以上是生活随笔為你收集整理的常用设计模式——职责链模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 初级、中级、高级测试/开发程序员的区别在
- 下一篇: Safety-Gym环境配置与安装