設計模式 如何優雅地使用責任鏈模式

2022-05-21 09:51:06 字數 3023 閱讀 5152

責任鏈模式(chain of responsibility pattern)在《head first設計模式》一書中被稱為「剩下的模式」,其實使用也是蠻多的。最近在學習netty的過程中用到了責任鏈模式,在此反過頭來重溫一下責任鏈模式。

當你想要讓乙個以上的物件有機會能夠處理某個請求的時候,就使用責任鏈模式。

talk is cheap. show me the code.直接用**來說話吧。

用列舉來定義四種型別的郵件:

public enum emailenum 

public integer getcode()

public string getdesc()

}

假設郵件有兩個屬性:郵件型別和郵件內容,定義郵件:

public class email 

public int gettype()

public string getcontent()

}

如果不採用責任鏈模式?使用emailhandler這個類來統一處理上述四種郵件,程式是這樣子的:

public class emailhandler 

if (emailenum.fan_email.getcode().equals(email.gettype()))

if (emailenum.complaint_email.getcode().equals(email.gettype())) else

}private void handlenewlocemail(email email)

private void handlecomplaintemail(email email)

private void handlefanemail(email email)

public void handlespamemail(email email)

}

這個類雖然強大,但是是不夠優雅的:

(1)emailhandler類較為龐大,各種型別郵件的處理都集中在乙個類中,違反了「單一職責原則」。

(2)如果之後增加新的郵件型別、刪除某一種郵件型別,或者有其他新功能的拓展,都必須修改源**並進行嚴格測試,違反了「開閉原則」。

開放-關閉原則:類應該對擴充套件開放,對修改關閉。

如何進行改進呢?那就是使用責任鏈模式,為某個請求建立乙個物件鏈。每個物件按照順序檢查這個請求,並對其處理,或者將它傳遞給鏈中的下乙個物件。在本例中,當收到電子郵件的時候,先進入第乙個處理器spamhandler,如果spamhandler無法處理,就將它傳給fanhandler,以此類推...

本例使用責任鏈模式的結構圖如圖所示:

handler是乙個抽象的處理器,是乙個抽象類。抽象類中定義了乙個抽象處理器的物件successor,通過該引用,可以形成一條責任鏈。抽象類中還定義了抽象處理請求的的方法handlerequest()。**如下:

public abstract class handler 

public abstract void handlerequest(email email);

}

spamhandler、fanhandler、complainthandler和newlochandler是具體的處理器,繼承抽象類handler,用來處理具體的郵件請求。處理細節:處理之前要進行型別的判斷,看是否能夠處理該請求,如果可以處理就處理,否則就**給後繼的處理器去處理。**如下:

spamhandler

public class spamhandler extends handler

else }}

fanhandler

public class fanhandler extends handler

else }}

complainthandler

public class complainthandler extends handler

else }}

newlochandler

public class newlochandler extends handler

else }}

需要注意的是,責任鏈模式並不建立責任鏈,責任鏈的建立工作必須由系統的其他部分來完成,一般是在使用該責任鏈的客戶端中建立責任鏈。責任鏈模式降低了請求的傳送端和接收端之間的耦合,使多個物件都有機會處理這個請求。下面編寫測試類進行測試:

public class test 

}

在**中建立四種型別的郵件用於處理,建立了四種不同的處理器(spamhandler、fanhandler、complainthandler、newlochandler),形成「handler1 -> handler2 -> handler3 -> handler4」的責任鏈,使用這條責任鏈處理四種型別的郵件。執行結構如下:

這樣處理之後,明顯使得請求傳送者和接受者解耦;每個實現類都有自己明確且獨一無二的職責;如果增加乙個型別,只需要再增加乙個具體類去繼承handler,書寫自己的處理邏輯,在責任鏈中進行新增;如果刪除某種型別的,只需要在構建責任鏈的時候,把它刪除就可以了,實現動態增加或者刪除責任,符合設計模式的原則。

責任鏈模式通過建立一條鏈來組織請求的處理者,請求將沿著鏈進行傳遞,請求傳送者無須知道請求在何時、何處以及如何被處理,實現了請求傳送者與處理者的解耦。在軟體開發中,如果遇到有多個物件可以處理同一請求時可以應用責任鏈模式,例如在web應用開發中建立乙個過濾器鏈來對請求資料進行過濾,在工作流系統中實現公文的分級審批等等,使用責任鏈模式可以較好地解決此類問題。

設計模式 責任鏈

使用情況描述 某人向銀行借錢 借1w一下一般櫃員就可以解決,借2w一下一般經理就能解決,如果借更多就需要主管才能解決。這就是乙個責任鏈,根據條件的不同,分別進行複雜的邏輯運算。if,switch都可以進行這樣的操作,但是需要在每一層進行一次複雜的操作。責任鏈模式是一種物件的行為模式。在責任鏈模式裡,...

責任鏈設計模式

責任鏈的應用場景 簡單使用責任鏈模式拆分 servlet api 中的過濾器 模擬servlet中的request物件 desc模擬 servlet 中的 request 物件 模擬servlet中的response物件 desc模擬 servlet 中的 response 物件 過濾器抽象層 de...

設計模式 責任鏈

引用 objective c程式設計之道 ios設計模式解析 責任鏈模式 使多個物件都有機會處理請求,從而避免請求的傳送者和接收者之間發生耦合。此模式將這些物件連成一條鏈,從而沿著這條鏈傳遞請求,直到有乙個物件處理它為止。責任鏈主要思想 很多物件引用了同一型別的另乙個物件,形成了一條鏈。鏈中每個物件...