20 設計模式之職責鏈模式(問題處理案例)

一、什么是職責鏈模式

????????職責鏈模式是一種行為型設計模式它允許將請求沿著處理者的鏈進行傳遞,直到有一個處理者能夠處理它為止。換句話說,它將請求的發送者和接收者解耦,使得多個對象都有機會處理這個請求,從而避免了將請求直接發送給具體的處理者。

????????在職責鏈模式中,多個處理者對象形成一個鏈,客戶端將請求傳遞給鏈中的第一個處理者,由第一個處理者決定是自己處理請求,還是將請求傳遞給下一個處理者,直到請求被處理或者鏈末尾沒有處理者為止。

二、職責鏈模式的結構

  • 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 中,我們創建了三個處理者(JuniorSupportTechSupportManagerSupport),并將它們串聯成一個處理鏈。當請求傳遞給第一個處理者時,若它不能處理請求,就將請求交給下一個處理者,直到找到合適的處理者或者到達鏈的末尾。

7. 總結

????????職責鏈模式通過將請求沿著處理者鏈進行傳遞,使得每個處理者只關心自己能處理的請求,從而減少了發送者與接收者之間的耦合。職責鏈模式有助于系統的靈活擴展,因為我們可以在運行時動態地調整處理鏈結構。通過這種模式,能夠實現請求的逐層處理,直到有一個處理者能夠處理該請求為止。

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

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

相關文章

linux基于systemd自啟守護進程 systemctl自定義服務傻瓜式教程

系統服務 書接上文: linux自啟任務詳解 演示系統:ubuntu 20.04 開發部署項目的時候常常有這樣的場景: 業務功能以后臺服務的形式提供,部署完成后可以隨著系統的重啟而自動啟動;服務異常掛掉后可以再次拉起 這個功能在ubuntu系統中通常由systemd提供 如果僅僅需要達成上述的場…

ros項目dual_arm_pick-place(moveit和gazebo聯合仿真)(一)

目錄 前言正文創建功能包具體代碼運行 總結 前言 dual_arm_pick-place項目中&#xff0c;實現了兩套的moveit和gazebo聯合仿真。 啟動文件分別是bringup_moveit.launch和arm_bringup_moveit.launch。 在這個項目中&#xff0c;我將代碼重新創建了一個包&#xff0c;co_simula…

MySQL 索引(B+樹)詳解

MySQL 索引&#xff08;B樹&#xff09;詳解 MySQL邏輯架構對比InnoDB與MyISAM存儲結構存儲空間可移植性、備份及恢復事務支持AUTO_INCREMENT表鎖差異全文索引表主鍵表的具體行數CRUD操作外鍵 sql優化簡介什么情況下進行sql優化sql語句執行過程sql優化就是優化索引 索引索引的優…

MySQL生產環境備份腳本

全量備份腳本&#xff0c;其中BakDir&#xff0c;ZlbakDir&#xff0c;LogFile需要自己創建 #!/bin/bash export LANGen_US.UTF-8# 指定備份目錄 BakDir/root/beifen/data/mysqlbak/data/allbak # 指定增量備份目錄 ZlbakDir/root/beifen/data/mysqlbak/data/zlbak # 備份日志…

HTTP multipart/form-data 請求

序言 最近在寫項目的過程中有一個需求是利用 HTTP 協議傳輸圖片和視頻&#xff0c;經過查詢方法相應的方法發現使用 multipart/form-data 的方式&#xff0c;這是最常見處理二進制文件的表單編碼類型。 ?學習了一下午&#xff0c;現在總結一下使用的方法和相關的知識點&#x…

Linux下redis環境的搭建

1.redis的下載 redis官網下載redis的linux壓縮包&#xff0c;官網地址:Redis下載 網盤鏈接&#xff1a; 通過網盤分享的文件&#xff1a;redis-5.0.4.tar.gz 鏈接: https://pan.baidu.com/s/1cz3ifYrDcHWZXmT1fNzBrQ?pwdehgj 提取碼: ehgj 2.redis安裝與配置 將包上傳到 /…

如何使用靜態IP代理?【詳細教程】

靜態IP地址是手動分配給設備或伺服器的固定不變的 IP。與動態 IP 地址不同&#xff0c;動態 IP 地址由 DHCP 伺服器自動分配&#xff0c;並且會隨時間而變化。??????? 如何獲取和設置靜態IP地址 一、檢查是否需要靜態IP&#xff1f; 在配置靜態 IP 之前&#xff0c;請…

監控組態軟件的構成與功能

監控組態軟件的構成包括系統開發環境、圖形界面系統、實時數據庫系統等。其功能包括數據采集與控制、人機交互界面、數據處理與存儲等。 監控組態軟件的構成&#xff1a; 系統開發環境&#xff1a;這是自動化工程設計工程師為實施其控制方案&#xff0c;在組態軟件的支持下進行…

Java 基礎之 XQuery:強大的 XML 查詢語言

一、什么是 XQuery XQuery 是一種函數式語言&#xff0c;專門用于檢索以 XML 格式存儲的信息。它負責從 XML 文檔中查找和提取元素及屬性&#xff0c;在網絡服務中有著廣泛的應用&#xff0c;比如提取信息、生成摘要報告、進行數據轉換等。 XQuery 是 W3C 設計的一種針對于 X…

day09性能測試(1)——純理論

document.querySelector(video).playbackRate 2.5 //可以寫任何數字 【沒有所謂的運氣&#x1f36c;&#xff0c;只有絕對的努力?】 目錄 1、性能測試概念 2、功能測試 vs 性能測試 3、小結&#xff08;習題&#xff09; 4、性能測試的策略 4.1 基準測試 4.2 負載測試 …

docker-3.docker權限問題

docker權限,每次開機都要重新sudo 目錄 1.簡介2.解決辦法1:當前用戶添加到docker用戶組(這個方法還是缺權限??)3.解決辦法2:臨時更改Docker socket文件權限1.簡介 Ubuntu下Docker提示permission denied (權限不足)解決辦法 安裝docker后,執行docker ps命令時提示 perm…

easyExcel實現表頭批注

背景&#xff1a; 網上大部分都不能直接使用&#xff0c;為此總結一個方便入手且可用的工具&#xff0c;用自定義注解實現 依賴包&#xff1a; <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>…

內部類和Object類

匿名對象 格式&#xff1a; 匿名對象只可以調用一次成員 &#xff1a; 1. 調用一次成員變量 &#xff1a; new 類名(實參).成員變量名&#xff1b; 2.調用一次成員方法&#xff1a; new 類名(實參).成員方法名(實參)&#xff1b; 匿名對象存在的必要&#xff1a;為了提高…

Python的3D可視化庫vedo 1-3 (visual模塊)網格對象的線和面、圖片的屬性

文章目錄 4 MeshVisual4.1 線條4.1.1 線寬和顏色4.1.2 線條渲染為管 4.2 曲面4.2.1 物體展示為實心或框架4.2.2 曲面插值4.2.3 面的剔除 4.3 紋理4.4 相機跟隨 5 ImageVisual5.1 圖片屬性5.1.1 占用內存大小5.1.2 顏色標量范圍 5.2 渲染屬性5.2.1 透明度5.2.2 亮度5.2.3 對比度…

19 設計模式之享元模式(電影院座位預定案例)

一、享元模式的定義 享元模式是一種結構型設計模式&#xff0c;它通過共享對象來支持大量細粒度的對象&#xff0c;減少內存消耗。享元模式的核心思想是&#xff1a;將對象分為共享部分和非共享部分&#xff0c;只有共享部分是被多個對象共享的&#xff0c;而非共享部分則是每個…

使用redis 的stream 做消息中間件 多線程消費消息

1.redis stream 特點 1.支持消息持久化 2.消費者組模式 3.消息確認機制 4. 消息重試機制 5. 死信隊列2. 消息生產者服務 2.1 如下代碼Service Slf4j public class StreamMessageProducer {Autowiredprivate StringRedisTemplate redisTemplate;private static final String S…

Python100道練習題

Python100道練習題 BIlibili 1、兩數之和 num1 20 num2 22result num1 num2print(result)2、一百以內的偶數 list1 []for i in range(1,100):if i % 2 0:list1.append(i) print(list1)3、一百以內的奇數 # 方法一 list1 [] for i in range(1,100):if i % 2 ! 0:lis…

Java轉C之并發和多線程

提綱&#xff1a; 概念介紹與對比概述 簡述Java與C在并發和多線程方面的核心區別解釋C11標準、POSIX、C11 <threads.h>、Pthread等名詞 Java多線程與并發回顧 線程、Runnable、ExecutorService概念說明同步關鍵字與工具類含義 C并發基礎 沒有Java式的內置線程類&#xf…

Ubuntu系統本地化搭建Maxakb+Ollama

安裝docker 最詳細的ubuntu 安裝 docker教程-騰訊云開發者社區-騰訊云 安裝Ollama Ollama官網 執行命令&#xff1a; curl -fsSL https://ollama.com/install.sh | sh安裝完成后下載模型 執行命令&#xff1a; ollama run llama3.3:70b安裝MaxKb 執行命令&#xff1a; d…

基于JAVA的旅游網站系統設計

摘要 隨著信息技術和網絡技術的迅速發展&#xff0c;人們的生活質量和觀念也在發生著改變&#xff0c;各地爭相發展旅游業&#xff0c;傳統的 旅游社已經無法滿足人們的需求&#xff0c;旅游網站將突破傳統在時間和地域的限制&#xff0c;成為方便、快捷、安全、可靠的旅游 方…