《C++新經典設計模式》之第19章 職責鏈模式

《C++新經典設計模式》之第19章 職責鏈模式

        • 職責鏈模式.cpp

職責鏈模式.cpp
#include <iostream>
#include <memory>
#include <string>
using namespace std;// 請求傳遞給鏈中的若干對象,哪個對象適合處理就自行處理
// 使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關系
// 將這些對象構成對象鏈,并沿著鏈傳遞請求,直到有對象處理為止// 3種角色
// Handler(處理者),定義處理請求的接口,記錄下一個處理者
// ConcreteHandler(具體處理者),實現針對具體請求的處理,自身無法處理會將請求傳遞給后繼者
// Client(請求者/客戶端),創建責任鏈,向責任鏈的具體處理者提交處理請求// 單純的責令鏈模式,請求得到處理后不向下傳遞
// 非單純的責令鏈模式(功能鏈),請求得到處理后繼續向下傳遞namespace ns1
{class SalaryHandler // 薪水處理類{void depManagerSP(const string &sname, int salfigure) const // 部門經理審批加薪請求{cout << sname << " ask for a raise: " << salfigure << ", manager agree!" << endl;}void CTOSP(const string &sname, int salfigure) const // 技術總監審批加薪請求{cout << sname << " ask for a raise: " << salfigure << ", Technical Director agree!" << endl;}void genManagerSP(const string &sname, int salfigure) const // 總經理審批加薪請求{cout << sname << " ask for a raise: " << salfigure << ", general manager agree!" << endl;}public:                                                         // 處理加薪請求void raiseRequest(const string &sname, int salfigure) const // 參數1代表要加薪的員工名字,參數2代表求要加薪多少{if (salfigure <= 1000) // 加薪要求不超過1000,部門經理可以批準depManagerSP(sname, salfigure);else if (salfigure <= 5000) // 加薪要求在1000元之上但不超過5000,技術總監才能批準CTOSP(sname, salfigure);else // 加薪要求超過5000元,總經理才能批準genManagerSP(sname, salfigure);}};
}namespace ns2
{class RaiseRequest // 加薪請求類{string m_sname;   // 請求加薪的人員名字int m_isalfigure; // 請求加薪的數字public:RaiseRequest(const string &sname, int salfigure) : m_sname(sname), m_isalfigure(salfigure) {}const string &getName() const { return m_sname; } // 獲取請求加薪的人員名字int getSalFigure() const { return m_isalfigure; } // 獲取請求加薪的數字};class ParSalApprover // 薪水審批者父類{shared_ptr<ParSalApprover> m_nextChain; // 指向下一個審批者(對象)的多態指針(指向自身類型),每個都指向下一個,就會構成一個職責鏈(鏈表)protected:void sendRequestToNextHandler(const RaiseRequest &req) const // 找鏈中的下個對象并把請求投遞給下個鏈中的對象{if (m_nextChain != nullptr)           // 找鏈中的下個對象m_nextChain->processRequest(req); // 把請求投遞給鏈中的下個對象else                                  // 沒找到鏈中的下個對象,程序流程執行這里似乎不應該cout << req.getName() << " ask for a raise: " << req.getSalFigure() << ", nobody agree!" << endl;}public:ParSalApprover(const shared_ptr<ParSalApprover> &next = nullptr) : m_nextChain(next) {}virtual ~ParSalApprover() {}void setNextChain(const shared_ptr<ParSalApprover> &next) { m_nextChain = next; } // 設置指向的職責鏈中的下個審批者virtual void processRequest(const RaiseRequest &req) const = 0;                   // 處理加薪請求};class depManager_SA : public ParSalApprover // 部門經理子類{public:depManager_SA(const shared_ptr<ParSalApprover> &next = nullptr) : ParSalApprover(next) {}void processRequest(const RaiseRequest &req) const override{int salfigure = req.getSalFigure();if (salfigure <= 1000) // 如果自己能處理,則自己處理cout << req.getName() << " ask for a raise: " << salfigure << ", manager agree!" << endl;else // 自己不能處理,嘗試找鏈中的下個對象來處理sendRequestToNextHandler(req);}};class CTO_SA : public ParSalApprover // 技術總監子類{public:CTO_SA(const shared_ptr<ParSalApprover> &next = nullptr) : ParSalApprover(next) {}void processRequest(const RaiseRequest &req) const override{int salfigure = req.getSalFigure();if (salfigure > 1000 && salfigure <= 5000) // 如果自己能處理,則自己處理cout << req.getName() << " ask for a raise: " << salfigure << ", CTO_SA agree!" << endl;elsesendRequestToNextHandler(req); // 自己不能處理,嘗試找鏈中的下個對象來處理}};class genManager_SA : public ParSalApprover // 總經理子類{public:genManager_SA(const shared_ptr<ParSalApprover> &next = nullptr) : ParSalApprover(next) {}void processRequest(const RaiseRequest &req) const override{int salfigure = req.getSalFigure();if (salfigure > 5000) // 如果自己能處理,則自己處理cout << req.getName() << " ask for a raise: " << salfigure << ", genManager_SA agree!" << endl;elsesendRequestToNextHandler(req); // 自己不能處理,嘗試找鏈中的下個對象來處理}};
}namespace ns3
{class ParWordFilter // 敏感詞過濾器父類{shared_ptr<ParWordFilter> m_nextChain{nullptr};protected: // 找鏈中的下個對象并把請求投遞給下個鏈中的對象string sendRequestToNextHandler(const string &strWord) const{if (m_nextChain != nullptr)                      // 找鏈中的下個對象return m_nextChain->processRequest(strWord); // 把請求投遞給鏈中的下個對象return strWord;}public:virtual ~ParWordFilter() {}void setNextChain(const shared_ptr<ParWordFilter> &next) { m_nextChain = next; } // 設置指向的職責鏈中的下個過濾器virtual string processRequest(const string &strWord) const = 0;                  // 處理敏感詞過濾請求};class SexyWordFilter : public ParWordFilter // 性敏感詞過濾器子類{public:string processRequest(const string &strWord) const override{cout << "replace sex with XXX!" << endl;return sendRequestToNextHandler(strWord + "XXX");}};class DirtyWordFilter : public ParWordFilter // 臟話詞過濾器子類{public:string processRequest(const string &strWord) const override{cout << "replace obscenities with YYY!" << endl;return sendRequestToNextHandler(strWord + "YYY");}};class PoliticsWordFilter : public ParWordFilter // 政治敏感詞過濾器子類{public:string processRequest(const string &strWord) const override{cout << "replace politices with ZZZ!" << endl;return sendRequestToNextHandler(strWord + "ZZZ");}};
}namespace ns4
{class AbstractLogger{public:static int INFO;static int DEBUG;static int ERROR;public:virtual ~AbstractLogger() = default;AbstractLogger(int m_level) : level(m_level) {}void setNextLogger(const shared_ptr<AbstractLogger> &m_nextLogger) { nextLogger = m_nextLogger; }void logMessage(int m_level, const string &message){if (level <= m_level)write(message);if (nextLogger != nullptr)nextLogger->logMessage(m_level, message);}protected:int level;shared_ptr<AbstractLogger> nextLogger;virtual void write(const string &message) const = 0;};int AbstractLogger::INFO = 1;int AbstractLogger::DEBUG = 2;int AbstractLogger::ERROR = 3;class ConsoleLogger : public AbstractLogger{public:ConsoleLogger(int level) : AbstractLogger(level) {}protected:void write(const string &message) const override{cout << "Standard Console::Logger: " + message << endl;}};class ErrorLogger : public AbstractLogger{public:ErrorLogger(int level) : AbstractLogger(level) {}protected:void write(const string &message) const override{cout << "ErrorLogger Console::Logger: " + message << endl;}};class FileLogger : public AbstractLogger{public:FileLogger(int level) : AbstractLogger(level) {}protected:void write(const string &message) const override{cout << "FileLogger Console::Logger: " + message << endl;}};shared_ptr<AbstractLogger> getChainOfLoggers(){shared_ptr<AbstractLogger> errorLogger = make_shared<ErrorLogger>(AbstractLogger::ERROR);shared_ptr<AbstractLogger> fileLogger = make_shared<FileLogger>(AbstractLogger::DEBUG);shared_ptr<AbstractLogger> consoleLogger = make_shared<ConsoleLogger>(AbstractLogger::INFO);errorLogger->setNextLogger(fileLogger);fileLogger->setNextLogger(consoleLogger);return errorLogger;}
}int main()
{
#if 0ns1::SalaryHandler sh;sh.raiseRequest("zs", 15000); // 張三要求加薪1.5萬sh.raiseRequest("ls", 3500);  // 李四要求加薪3千5sh.raiseRequest("we", 800);   // 王二要求加薪8百
#endif#if 0using namespace ns2;//(1)創建出職責鏈中包含的各個對象(部門經理、技術總監、總經理)shared_ptr<ParSalApprover> pzzlinkobj3(new genManager_SA());shared_ptr<ParSalApprover> pzzlinkobj2(new CTO_SA(pzzlinkobj3));shared_ptr<ParSalApprover> pzzlinkobj1(new depManager_SA(pzzlinkobj2));//(2)將這些對象串在一起構成職責鏈(鏈表),現在職責鏈中pzzlinkobj1排在最前面,pzzlinkobj3排在最后面// pzzlinkobj1->setNextChain(pzzlinkobj2);// pzzlinkobj2->setNextChain(pzzlinkobj3);// pzzlinkobj3->setNextChain(nullptr); //可以不寫此行,因為ParSalApprover構造函數中設置了m_nextChain為nullptr//(3)創建幾位員工關于加薪的請求(對象)RaiseRequest emp1Req("zs", 15000); // 張三要求加薪1.5萬RaiseRequest emp2Req("ls", 3500);  // 李四要求加薪3千5RaiseRequest emp3Req("we", 800);   // 王二要求加薪8百// 看看每位員工的加薪請求由職責鏈中的哪個對象(部門經理、技術總監、總經理)來處理,從職責鏈中排在最前面的接收者(pzzlinkobj1)開始pzzlinkobj1->processRequest(emp1Req);pzzlinkobj1->processRequest(emp2Req);pzzlinkobj1->processRequest(emp3Req);
#endif#if 0using namespace ns3;//(1)創建出職責鏈中包含的各個對象(性敏感詞過濾器、臟話詞過濾器、政治敏感詞過濾器)shared_ptr<ParWordFilter> pwflinkobj1(new SexyWordFilter());shared_ptr<ParWordFilter> pwflinkobj2(new DirtyWordFilter());shared_ptr<ParWordFilter> pwflinkobj3(new PoliticsWordFilter());//(2)將這些對象串在一起構成職責鏈(鏈表),現在職責鏈中pwflinkobj1排在最前面,pwflinkobj3排在最后面pwflinkobj1->setNextChain(pwflinkobj2);pwflinkobj2->setNextChain(pwflinkobj3);pwflinkobj3->setNextChain(nullptr);// 從職責鏈中排在最前面的接收者(pwflinkobj1)開始,processRequest的參數代表的是聊天內容string strWordFilterResult = pwflinkobj1->processRequest("Hello, here is an example of filtering sensitive words test");cout << "The result of filtering sensitive words is: " << strWordFilterResult << endl;
#endif#if 1using namespace ns4;shared_ptr<AbstractLogger> loggerChain = getChainOfLoggers();loggerChain->logMessage(AbstractLogger::INFO, "This is an information.");loggerChain->logMessage(AbstractLogger::DEBUG, "This is a debug level information.");loggerChain->logMessage(AbstractLogger::ERROR, "This is an error information.");
#endifcout << "Over!\n";return 0;
}

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

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

相關文章

后端返回base64文件前端如何下載

1.后端返回base64格式文件 2.前端代碼 <style lang"less" scoped> import "./style/common.less";.table-div-a {color: #409EFF;text-decoration: underline;cursor: pointer; } </style><template><div class"template-con…

一文搞懂什么是Hadoop

Hadoop概念 什么是Hadoop Hadoop是一個由Apache基金會所開發的用于解決海量數據的存儲及分析計算問題的分布式系統基礎架構。 廣義上來說&#xff0c;Hadoop通常指一個跟廣泛的概念——Hadoop生態圈。 以下是hadoop生態圈中的技術&#xff1a; Hadoop優勢 hadoop組成 HDFS…

一個不錯的文章偽原創系統程序源碼

一款文章偽原創系統程序源碼免費分享&#xff0c;程序是站長原創的。 一共花了站長幾天時間寫的這個文章偽原創平臺&#xff0c;程序無需數據庫。 程序前端采用BootStrap框架搭建&#xff0c;后端采用PHP原生書寫。 前端偽原創采用Ajax無刷新提交&#xff0c;Ajax轉換到詞庫…

TCPUDP使用場景討論

將鏈路從TCP改為UDP會對通信鏈路產生以下影響和注意事項&#xff1a; 可靠性&#xff1a;UDP是無連接的協議&#xff0c;與TCP相比&#xff0c;它不提供可靠性保證和重傳機制。因此&#xff0c;當將鏈路從TCP改為UDP時&#xff0c;通信的可靠性會降低。如果在通信過程中丟失了U…

【爬取二手車并將數據保存在數據庫中】

爬取二手車并將數據保存在數據庫中 查看網頁結構分析爬取步驟解密加密信息將密文解密代碼&#xff1a; 進行爬取&#xff1a;爬取函數寫入解密文件函數和獲取城市函數解密文件&#xff0c;返回正確字符串函數保存到數據庫 運行結果 查看網頁結構分析爬取步驟 可以看出網頁使用…

C 語言 變量

變量初始值 全局變量&#xff1a;初始值是 0 局部變量&#xff1a;初始值是 隨機的 類型限定符 通常不需要顯式使用 register 關鍵字來優化變量的存儲和訪問。 關鍵字 _Complex和_Imaginary分別用于表示復數和虛數&#xff08;二者皆是數學概念&#xff09; 變量的聲明和定義 c…

蘋果 macOS 14.1.2 正式發布 更新了哪些內容?

蘋果今日向 Mac 電腦用戶推送了 macOS 14.1.2 更新&#xff08;內部版本號&#xff1a;23B92 | 23B2091&#xff09;&#xff0c;本次更新距離上次發布隔了 28 天。 需要注意的是&#xff0c;因蘋果各區域節點服務器配置緩存問題&#xff0c;可能有些地方探測到升級更新的時間略…

webWorker解決單線程中的一些小問題和性能優化

背景 js是單線程這是大家都知道&#xff0c;為了防止多個線程同時操作DOM&#xff0c;這個導致一個復雜的同步問題。比如&#xff0c;假定JavaScript同時有兩個線程&#xff0c;一個線程在某個DOM節點上添加內容&#xff0c;另一個線程刪除了這個節點&#xff0c;這時瀏覽器應…

全局平均池化的示例

1.對一個3通道&#xff0c;5*5的矩陣&#xff0c;進行全局平均池化 每個矩陣的大小都是 5x5&#xff0c;假設這些矩陣代表一幅圖像的三個不同通道。為簡單起見&#xff0c;我們將這三個矩陣分別稱為 A、B 和 C。合成圖像將是一個三通道圖像&#xff0c;每個通道由其中一個矩陣…

計算機方向的一些重要縮寫和簡介

參考&#xff1a; 深度學習四大類網絡模型 干貨|機器學習超全綜述&#xff01; 機器學習ML、卷積神經網絡CNN、循環神經網絡RNN、馬爾可夫蒙特卡羅MCMC、生成對抗網絡GAN、圖神經網絡GNN——人工智能經典算法 MLP&#xff08;Multi Layer Perseption&#xff09;用在神經網絡中…

這是最后的戰役了

不變因子 初等因子 行列式因子 smith標準型 酉矩陣 H-陣等等 A H A A^H A AHA 就是 H-陣 正定H陣的性質 若 A A A 為正定的H-陣. 存在可逆矩陣 Q Q Q&#xff0c; 使得 A Q H Q AQ^H Q AQHQ.存在 P P P, 使得 P H A P I P^HAPI PHAPI.A的特征值大于0. Q ? 1 A Q Q^{…

駕馭蘋果的人工智慧模式:克服反擊與應對挑戰

蘋果一年一度的秋季「春晚」時間越來越近&#xff0c;但在大模型浪潮下&#xff0c;蘋果何時推出自己的「蘋果GPT」成了另一個關注的話題。 畢竟&#xff0c;前有華為&#xff0c;后有小米&#xff0c;在中國手機廠商爭相將大模型裝進移動終端的同時&#xff0c;蘋果卻依舊對A…

微服務學習:Ribbon實現客戶端負載均衡,將請求分發到多個服務提供者

Ribbon是Netflix開源的一個基于HTTP和TCP客戶端負載均衡器。它主要用于在微服務架構中實現客戶端負載均衡&#xff0c;將請求分發到多個服務提供者上&#xff0c;從而實現高可用性和擴展性。 Ribbon的主要特點包括&#xff1a; 客戶端負載均衡&#xff1a;Ribbon是一個客戶端負…

【算法題】找出符合要求的字符串子串(js)

題解&#xff1a; function solution(str1, str2) {const set1 new Set([...str1]);const set2 new Set([...str2]);return [...set1].filter((item) > set2.has(item)).sort();}console.log(solution("fach", "bbaaccedfg"));//輸入:fach// bbaacced…

手機上寫工作總結用什么軟件好?借助工作筆記輕松寫出優秀年終總結

隨著年底的臨近&#xff0c;撰寫個人年終工作總結成為了許多職場人士的重要任務。因為手機是每個上班族都要隨身攜帶的電子設備&#xff0c;所以想要抽時間來寫年終工作總結&#xff0c;使用手機是比較便捷的。那么&#xff0c;在手機上寫工作總結應該使用什么軟件呢&#xff1…

Linux 環境下的性能測試——top與stress

對于Linux 環境&#xff0c;top命令是使用頻繁且信息較全的命令&#xff0c; 它對于所有正在運行的進行和系統負荷提供實時更新的概覽信息。stress是個簡單且全面的性能測試工具。通過它可以模擬各種高負載情況。 通過top與stress這兩個命令的結合使用&#xff0c;基本可以達到…

軟件測試——單元測試

單元測試是軟件開發中的一種測試方法&#xff0c;用于驗證軟件中的各個獨立單元&#xff08;通常是函數、方法或類&#xff09;是否按照設計規范正常工作。以下是進行單元測試的一般步驟和最佳實踐&#xff1a; 1. 選擇測試框架 選擇適合項目的測試框架&#xff0c;例如&…

SHAP:Python的可解釋機器學習庫

SHAP:Python的可解釋機器學習庫 一、概念二、步驟三、代碼-以波士頓房價為例summary_plotFeature Importanceshap_interaction_valuesdependence_plot完整代碼一、概念 SHAP(Shapley Additive Explanations)模型是一種用于解釋機器學習模型預測結果的方法。它基于合作博弈論…

【C++】類和對象——explicit關鍵字,友元和內部類

這篇博客已經到了類和對象的最后一部分了&#xff0c;下面我們先看一下explicit關鍵字 我們還是先來引入一個例子&#xff0c;我們的代碼是可以這么寫的 class A { public:A(int aa 0) {_a aa;cout << "A(int aa 0)" << endl;} private:int _a; }; i…

紅隊攻防實戰之Redis-RCE集錦

心若有所向往&#xff0c;何懼道阻且長 Redis寫入SSH公鑰實現RCE 之前進行端口掃描時發現該機器開著6379&#xff0c;嘗試Redis弱口令或未授權訪問 嘗試進行連接Redis&#xff0c;連接成功&#xff0c;存在未授權訪問 嘗試寫入SSH公鑰 設置redis的備份路徑 設置保存文件名 …