【重溫設計模式】職責鏈模式及其Java示例

職責鏈模式的介紹

在開發過程中,我們經常會遇到這樣的問題:一個請求需要經過多個對象的處理,但是我們并不知道具體由哪個對象來處理,或者說,我們希望由接收到請求的對象自己去決定如何處理或者是將請求傳遞給下一個對象處理。這種情況下,我們可以使用一種被稱為"職責鏈模式"的設計模式來解決這個問題。

職責鏈模式,也被稱為鏈式處理模式,它是一種行為型設計模式,其主要思想是讓多個對象都有機會處理請求,從而解耦了請求的發送者和接收者。在這個模式中,請求會從鏈條的一端開始,沿著鏈條逐個傳遞,直到有一個對象處理它為止。這種模式在軟件開發中的應用場景非常廣泛,比如在Java的Servlet中,當一個http請求到達服務器時,它可能需要經過多個Filter的處理,這種場景就可以使用職責鏈模式來實現。

Java中的職責鏈模式實例

在我們了解了職責鏈模式的基本概念和應用場景后,接下來,我們將通過一個具體的Java實例,展示如何在實際開發中使用職責鏈模式,以及如何通過職責鏈模式解決實際問題。

假設我們正在開發一個處理用戶請求的系統,每個請求都有一個處理級別。我們有三個處理器,他們分別處理不同級別的請求。我們可以使用職責鏈模式來處理這個問題。首先,我們需要定義一個處理器類,這個類有一個處理請求的方法和一個設置下一個處理器的方法。下面是處理器類的代碼:

public abstract class Handler {protected Handler successor;public void setSuccessor(Handler successor) {this.successor = successor;}public abstract void handleRequest(int requestLevel);
}

然后,我們可以定義三個具體的處理器類,它們都繼承自處理器類:

public class HandlerOne extends Handler {public void handleRequest(int requestLevel) {if (requestLevel <= 1) {System.out.println("HandlerOne has handled the request.");} else if (successor != null) {successor.handleRequest(requestLevel);}}
}public class HandlerTwo extends Handler {public void handleRequest(int requestLevel) {if (requestLevel <= 2) {System.out.println("HandlerTwo has handled the request.");} else if (successor != null) {successor.handleRequest(requestLevel);}}
}public class HandlerThree extends Handler {public void handleRequest(int requestLevel) {if (requestLevel <= 3) {System.out.println("HandlerThree has handled the request.");} else {System.out.println("No handler can handle the request.");}}
}

最后,我們可以在主函數中創建處理器對象,并設置它們的職責鏈:

public class OneMore {public static void main(String[] args) {HandlerOne handlerOne = new HandlerOne();HandlerTwo handlerTwo = new HandlerTwo();HandlerThree handlerThree = new HandlerThree();handlerOne.setSuccessor(handlerTwo);handlerTwo.setSuccessor(handlerThree);handlerOne.handleRequest(2);}
}

這樣,當我們有一個請求時,我們只需要將請求傳遞給鏈條的第一個處理器,它會根據請求的級別來決定是自己處理還是傳遞給下一個處理器。這就是職責鏈模式的基本用法。

在這個例子中,我們可以看到,職責鏈模式可以很好地將請求的發送者和接收者解耦,使得請求的發送者不需要知道請求的接收者是誰,請求的接收者也不需要知道請求的發送者是誰。這樣,我們就可以靈活地改變處理器的組合和順序,而不會影響到請求的發送者。

然而,職責鏈模式并不是萬能的。接下來,我們將探討職責鏈模式的優缺點,以及在何種情況下使用職責鏈模式是合適的,以及在何種情況下不建議使用。

職責鏈模式的優缺點

職責鏈模式的一個顯著優點是它可以降低對象之間的耦合度。在職責鏈模式中,一個請求可以被任何處理請求的對象處理,這樣,發送者和接收者的耦合度就被降低了。它也支持動態的添加或者刪除責任對象,可以在運行時改變鏈中的成員或者調整它們的順序,這提供了很高的靈活性。此外,職責鏈模式還可以控制請求的處理過程,請求者不必知道請求在何時、如何、被誰處理,只需將請求發送到鏈上即可。

然而,職責鏈模式也有其不足之處。首先,它不能保證每個請求都會被處理,如果所有的處理對象都不處理請求,那么請求就會被丟棄。此外,如果責任鏈過長,請求的處理可能會涉及多個處理對象,這將導致系統性能的降低。因此,使用職責鏈模式時,需要慎重考慮如何定義和組織責任鏈。

那么,在何種情況下使用職責鏈模式是合適的呢?當一個系統的功能分解成多個處理對象,且這些對象有明確的順序關系時,可以考慮使用職責鏈模式。例如,一個訂單處理系統,訂單的處理流程可能包括訂單校驗、庫存檢查、支付處理等步驟,這些步驟就可以組成一個責任鏈。

反之,在何種情況下不建議使用職責鏈模式呢?如果一個系統的功能不能分解為多個處理對象,或者處理對象之間沒有明確的順序關系,那么使用職責鏈模式可能會引入不必要的復雜性。例如,一個簡單的數據查詢系統,數據的查詢并不需要經過多個處理步驟,此時使用職責鏈模式可能會讓系統變得復雜。

總結

職責鏈模式是一種強大而靈活的設計模式,它可以幫助我們設計出解耦度高、可擴展性強的系統。然而,這并不意味著我們應該在所有情況下都使用職責鏈模式。在使用任何設計模式時,我們都應該充分理解其優缺點,以及適用和不適用的情況,然后根據實際的需求和情況來做出合理的選擇。

在這個過程中,我們應該始終記住,設計模式只是工具,而不是目標。我們的目標是設計出高質量的軟件,而設計模式只是幫助我們達到這個目標的手段。我們應該根據實際的需求和情況,靈活地使用和組合各種設計模式,而不是盲目地追求使用某種設計模式。

總的來說,職責鏈模式是一種有用的設計模式,它可以幫助我們解決一些特定的設計問題。然而,無論是使用職責鏈模式,還是其他的設計模式,我們都應該以實際的需求為出發點,以提高軟件的質量為目標,靈活地使用和組合各種設計模式,以實現最佳的設計。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/716786.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/716786.shtml
英文地址,請注明出處:http://en.pswp.cn/news/716786.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

CSS 選擇器的常見用法

這里CSS選擇器主要分為以下這幾種&#xff1a;1. 標簽選擇器 2. class選擇器 3. id選擇器 4. 復合選擇器 5. 通配符選擇器 CSS 選擇器的主要功能就是選中??指定的標簽元素. 選中了元素, 才可以設置元素的屬性. 1.標簽選擇器 <style>p{color: red;} </style> &…

表單控件上的事件

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>光標聚焦和失焦事件</title><style type"text/css">.text{color: red;font-size: 12px;}</style> </head> <bod…

【深度學習筆記】計算機視覺——錨框

錨框 目標檢測算法通常會在輸入圖像中采樣大量的區域&#xff0c;然后判斷這些區域中是否包含我們感興趣的目標&#xff0c;并調整區域邊界從而更準確地預測目標的真實邊界框&#xff08;ground-truth bounding box&#xff09;。 不同的模型使用的區域采樣方法可能不同。 這里…

吳恩達deeplearning.ai:正則化對于偏方差的影響制定用于性能評估的基準

以下內容有任何不理解可以翻看我之前的博客哦&#xff1a;吳恩達deeplearning.ai專欄 這節我們看看正則化系數 文章目錄 以線性回歸為例交叉驗證誤差對于確定 λ \lambda λ的作用 指定用于性能評估的基準語音識別的例子 以線性回歸為例 讓我們舉一個例子&#xff1a; 模型&am…

Outlook郵箱IMAP密碼怎么填寫?賬戶設置?

Outlook郵箱IMAP密碼是什么&#xff1f;Outlook如何設置IMAP&#xff1f; 許多用戶會選擇通過IMAP協議將郵箱與各種郵件客戶端進行連接。而在設置過程中&#xff0c;填寫IMAP密碼是必不可少的一步。那么&#xff0c;Outlook郵箱的IMAP密碼應該如何填寫呢&#xff1f;接下來&am…

【Linux】深入理解ls命令

&#x1f34e;個人博客&#xff1a;個人主頁 &#x1f3c6;個人專欄&#xff1a;Linux ?? 功不唐捐&#xff0c;玉汝于成 目錄 前言 正文 基本用法 常用選項 示例 高級用法 結語 我的其他博客 前言 在 Linux 系統中&#xff0c;ls 命令是一個強大而又基礎的工具&am…

高刷顯示器 - HKC VG253KM

&#x1f525;&#x1f525; 今天來給大家揭秘一款電競神器 - HKC VG253KM 高刷電競顯示器&#xff01;這款顯示器可是有著雄鷹展翅般的設計靈感&#xff0c;背后的大鵬展翅鷹翼圖騰讓人過目難忘。那么&#xff0c;這款顯示器到底有哪些過人之處呢&#xff1f;一起來看看吧&…

【MySQL】基于Docker搭建MySQL一主二從集群

本文記錄了搭建mysql一主二從集群&#xff0c;這樣的一個集群master為可讀寫&#xff0c;slave為只讀。過程中使用了docker&#xff0c;便于快速搭建單體mysql。 1&#xff0c;準備docker docker的安裝可以參考之前基于yum安裝docker的文章[1]。 容器相關命令[2]。 查看正在…

如何系統的學習Python——Python的基本語法

學習Python的基本語法是入門的第一步&#xff0c;以下是一些常見的基本語法概念&#xff1a; 注釋&#xff1a; 用#符號來添加單行注釋&#xff0c;或使用三引號(或""")來添加多行注釋。 # 這是一個單行注釋 這是 多行 注釋 變量和數據類型&#xff1a; 變量用…

Pod和容器設計模式

為什么需要 Pod&#xff1b; Pod 的實現機制&#xff1b; 詳解容器設計模式。 一、為什么需要 Pod 容器的基本概念 現在來看第一個問題&#xff1a;為什么需要 Pod&#xff1f;我們知道 Pod 是 Kubernetes 項目里面一個非常重要的概念&#xff0c;也是非常重要的一個原子調…

144. 二叉樹的前序遍歷

給你二叉樹的根節點 root &#xff0c;返回它節點值的 前序 遍歷。 示例 1&#xff1a; 輸入&#xff1a;root [1,null,2,3] 輸出&#xff1a;[1,2,3]示例 2&#xff1a; 輸入&#xff1a;root [] 輸出&#xff1a;[]示例 3&#xff1a; 輸入&#xff1a;root [1] 輸出&am…

java方法

目錄 方法的定義 方法的命名規則 方法的調用與重載 方法調用實例 方法的重載 變量的作用域 算法中常見的方法 1&#xff1a;gcd&#xff08;求兩個整數中的最大公約數&#xff09; 2&#xff1a;lcm&#xff08;求兩個整數的最小公倍數&#xff09; 3:判斷一個整數是否…

SpringCloud(18)之Sleuth +Zipkin鏈路追蹤

一、Zipkin介紹 Zipkin是一個開放源代碼分布式的跟蹤系統&#xff0c;它可以幫助收集服務的時間數據&#xff0c;以解決微服務架構中的延遲問 題&#xff0c;包括數據的收集、存儲、查找和展現。每個服務向zipkin報告計時數據&#xff0c;zipkin會根據調用關系通 過Zipkin UI…

LeetCode: 數組中的第K個最大元素

問題描述 在未排序的數組中找到第k個最大的元素。請注意&#xff0c;你需要找的是數組排序后的第k個最大的元素&#xff0c;而不是第k個不同的元素。 解題思路 解決這個問題有多種方法&#xff0c;下面是幾種常見的解題策略&#xff1a; 排序后選擇: 將數組排序&#xff0c…

ProChat 如何接入 WebSocket

WebSocket是一種在單個TCP連接上進行全雙工通信的協議&#xff0c;允許客戶端和服務器之間進行雙向實時通信。與Server-Sent Events (SSE)類似&#xff0c;WebSocket也能實現實時數據推送&#xff0c;但其功能更為強大且靈活。 全雙工通信&#xff1a;WebSocket不僅允許服務器向…

【TestNG】(4) 重試機制與監聽器的使用

在UI自動化測試用例執行過程中&#xff0c;經常會有很多不確定的因素導致用例執行失敗&#xff0c;比如網絡原因、環境問題等&#xff0c;所以我們有必要引入重試機制&#xff08;失敗重跑&#xff09;&#xff0c;來提高測試用例成功率。 在不寫代碼的情況沒有提供可配置方式…

Mysql 慢查詢日志

查詢是否開啟慢SQL日志 show variables like %slow_query_log; 開啟慢查詢日志 set global slow_query_logON; 可以通過修改MySQL的配置my.cfg或者my.ini永久生效 slow_query_logON # 開啟慢查詢日志開關 slow_query_log_file/var/lib/mysql/alvin-slow.log # 慢查詢日志…

1.2 在卷積神經網絡中,如何計算各層感受野的大小

1.2 在卷積神經網絡中&#xff0c;如何計算各層感受野的大小 分析與解答&#xff1a; 在卷積神經網絡中&#xff0c;由于卷積的局部連接性&#xff0c;輸出特征圖上的每個節點的取值&#xff0c;是由卷積核在輸入特征圖對應位置的局部區域內進行卷積而得到的&#xff0c;因此這…

COM - IWbemClassObject對象屬性的遍歷

文章目錄 COM - IWbemClassObject對象屬性的遍歷概述筆記場景封裝好的函數bool CWmiBase::enumObjVaule(IWbemClassObject* obj, std::wstring& val)bool CWmiBase::appendVarToString(BSTR& strName, VARIANT& var, std::wstring& val)bool CWmiBase::get_var…

【筆試強訓錯題選擇題】Day5.習題(錯題)解析

文章目錄 前言 錯題題目 錯題解析 總結 前言 錯題題目 1. ? ? 2. 3. ? 4. ? 5. ? 錯題解析 1. 移位運算符的使用 2. 3. 4. 5. 總結