中介者和訪問者模式(行為型設計模式)的 C++ 代碼示例模板

文章目錄

  • 前言
  • 代碼倉庫
  • 中介者模式(Mediator)
  • 訪問者模式(Visitor)
  • 總結
  • 參考資料
  • 作者的話

前言

中介者和訪問者模式(行為型設計模式)的 C++ 代碼示例模板。


代碼倉庫

  • yezhening/Programming-examples: 編程實例 (github.com)
  • Programming-examples: 編程實例 (gitee.com)

中介者模式(Mediator)

結構

  • 抽象同事類
  • 抽象中介者類
  • 具體中介者類 (協調交互 的對象)
  • 具體同事類 (需要交互 的對象)
  • 抽象同事類 封裝 抽象中介者指針(實際上指向一個具體中介者對象)(同事 需要認識 中介者)、發送消息方法 和 接收消息方法
  • 抽象中介者類 封裝 轉發消息方法
  • 具體中介者類 封裝 抽象同事指針(實際上指向一個具體同事對象)(中介者 需要認識 同事)
  • 具體中介者類 重寫 轉發消息方法 (形式上 調用 具體中介者類的 轉發消息方法,實際上 調用 具體同事類的 接收消息方法(中介者 轉發消息,同事 接收消息))
  • 具體同事類 重寫 發送消息方法 (形式上 調用 具體同事類的 發送消息方法,實際上 調用 具體中介者類的 轉發消息方法(當前同事 發送消息,委托 中介者 轉發消息)) 和 接收消息方法

代碼

#include <string>
#include <iostream>using std::cout;
using std::endl;
using std::string;// 注意 類的定義順序
// 前置聲明
class AbstractMediator;// 抽象同事類
class AbstractColleague
{
public:AbstractColleague(AbstractMediator *mediator) : mediator(mediator) {}// 發送消息virtual void send_message(string message) = 0;// 接收消息virtual void recv_message(string message) = 0;protected:// 抽象中介者指針(實際上指向一個具體中介者對象)(同事 需要認識 中介者)AbstractMediator *mediator;
};// 抽象中介者類
class AbstractMediator
{
public:// 轉發消息virtual void forward_message(string message, AbstractColleague *colleague) = 0;
};// 具體中介者類(協調交互 的對象)
class ConcreteMediator : public AbstractMediator
{
public:// 設置同事void set_colleague_A(AbstractColleague *colleague){this->colleague_A = colleague;}void set_colleague_B(AbstractColleague *colleague){this->colleague_B = colleague;}// 轉發消息void forward_message(string message, AbstractColleague *colleague) override // 形式上 調用 具體中介者類的 轉發消息方法{if (colleague == this->colleague_A){this->colleague_B->recv_message(message); // 實際上 調用 具體同事類的 接收消息方法(中介者 轉發消息,同事 接收消息)}else if (colleague == this->colleague_B) // 發送者 是 同事B{this->colleague_A->recv_message(message); // 接收者 是 同事A}}private:// 抽象同事指針(實際上指向一個具體同事對象)(中介者 需要認識 同事)AbstractColleague *colleague_A;AbstractColleague *colleague_B;
};// 具體同事A類(需要交互 的對象)
class ConcreteColleagueA : public AbstractColleague
{
public:ConcreteColleagueA(AbstractMediator *mediator) : AbstractColleague(mediator) {}// 發送消息void send_message(string message) override // 形式上 調用 具體同事A類的 發送消息方法{cout << "Colleague A sends message: " << message << endl;mediator->forward_message(message, this); // 實際上 調用 具體中介者類的 轉發消息方法(當前同事 發送消息,委托 中介者 轉發消息)。發送者 是 同事A(this)}// 接收消息void recv_message(string message) override{std::cout << "Colleague A receives message: " << message << std::endl;}
};// 具體同事類B
class ConcreteColleagueB : public AbstractColleague
{
public:ConcreteColleagueB(AbstractMediator *mediator) : AbstractColleague(mediator) {}void send_message(string message) override{cout << "Colleague B sends message: " << message << endl;mediator->forward_message(message, this);}void recv_message(string message) override{cout << "Colleague B receives message: " << message << endl;}
};// 客戶端
int main()
{// 具體中介者指針(實際上指向一個具體中介者對象)ConcreteMediator *mediator = new ConcreteMediator();// 具體同事指針(實際上指向一個具體同事對象)(同事 需要認識 中介者)ConcreteColleagueA *colleague_A = new ConcreteColleagueA(mediator);ConcreteColleagueB *colleague_B = new ConcreteColleagueB(mediator);// 設置中介者的同事對象(中介者 需要認識同事)mediator->set_colleague_A(colleague_A);mediator->set_colleague_B(colleague_B);// 同事對象間 委托中介者 交互colleague_A->send_message("Hello from Colleague A");colleague_B->send_message("Hi from Colleague B");delete colleague_B;delete colleague_A;delete mediator;return 0;
}
/*
輸出:
Colleague A sends message: Hello from Colleague A
Colleague B receives message: Hello from Colleague A
Colleague B sends message: Hi from Colleague B
Colleague A receives message: Hi from Colleague B
*/

訪問者模式(Visitor)

結構

  • 抽象訪問者類
  • 抽象元素類
  • 具體元素類
  • 具體訪問者類
  • 對象結構類
  • 抽象訪問者類 封裝 訪問方法(接收參數是具體元素指針)
  • 抽象元素類 封裝 接收方法(接收參數是抽象訪問者指針)
  • 具體元素類 重寫 接收方法 (形式上 調用 具體元素類的 接收方法,實際上 調用 具體訪問者類的 訪問方法。發送參數是 this,表示 允許 訪問者 訪問 自身), 封裝操作方法
  • 具體訪問者類 重寫 訪問方法 (形式上 調用 具體訪問者類的 訪問方法,實際上 調用 具體元素類的 操作方法)
  • 對象結構類 封裝 抽象元素指針(實際上指向一個具體元素對象)的集合、添加元素方法 和 接收方法 (形式上 調用 對象結構類的 接收方法,實際上 調用 具體元素類的 接收方法)

訪問過程

  • 對象結構類的 接收方法,發送參數是 訪問者對象(對象結構 需要 訪問者訪問)
  • 具體元素類的 接收方法,發送參數是 訪問者對象(元素 需要 訪問者訪問)
  • 具體訪問者類的 訪問方法,發送參數是 具體元素對象(元素 允許 訪問者訪問)
  • 具體訪問者類的 操作方法(訪問者 訪問 元素)

重點理解

  • 分離 穩定的數據結構(元素) 和 變化的算法(訪問者)
  • 當需要添加新的操作時,只需要創建新的訪問者類并實現相應的方法,而不需要修改現有的元素類

代碼

#include <iostream>
#include <vector>using std::cout;
using std::endl;
using std::vector;// 注意 類的定義順序
// 前置聲明
class ConcreteElementA;
class ConcreteElementB;// 抽象訪問者類
class AbstractVisitor
{
public:// 訪問virtual void visit_element_A(ConcreteElementA *element) = 0; // 接收參數是具體元素指針virtual void visit_element_B(ConcreteElementB *element) = 0;
};// 抽象元素類
class AbstractElement
{
public:// 接收virtual void accept(AbstractVisitor *visitor) = 0; // 接收參數是抽象訪問者指針
};// 具體元素 A 類
class ConcreteElementA : public AbstractElement
{
public:// 接收void accept(AbstractVisitor *visitor) override // 形式上 調用 具體元素類的 接收方法{visitor->visit_element_A(this);// 實際上 調用 具體訪問者類的 訪問方法// 發送參數是 this,表示 允許 訪問者 訪問 自身}// 操作void operation_A(){cout << "ConcreteElementA operation" << endl;}
};// 具體元素B類
class ConcreteElementB : public AbstractElement
{
public:void accept(AbstractVisitor *visitor) override{visitor->visit_element_B(this);}void operation_B(){cout << "ConcreteElementB operation" << endl;}
};// 具體訪問者類
class ConcreteVisitor : public AbstractVisitor
{
public:// 訪問void visit_element_A(ConcreteElementA *element) override // 形式上 調用 具體訪問者類的 訪問方法{cout << "ConcreteVisitor visits ConcreteElementA" << endl;element->operation_A(); // 實際上 調用 具體元素類的 操作方法}void visit_element_B(ConcreteElementB *element) override{cout << "ConcreteVisitor ConcreteElementB" << endl;element->operation_B();}
};// 當需要添加新的操作時,只需要創建新的訪問者類并實現相應的方法,而不需要修改現有的元素類
// 具體訪問者新類
class ConcreteVisitorNew : public AbstractVisitor
{
public:// 訪問// 新的操作void visit_element_A(ConcreteElementA *element) override{cout << "ConcreteVisitorNew visits ConcreteElementA" << endl;element->operation_A();}void visit_element_B(ConcreteElementB *element) override{cout << "ConcreteVisitorNew ConcreteElementB" << endl;element->operation_B();}
};// 對象結構類
class ObjectStructure
{
public:// 添加元素void add_element(AbstractElement *element){this->element_vec.push_back(element);}// 移除元素// 接收void accept(AbstractVisitor *visitor) // 形式上 調用 對象結構類的 接收方法{for (AbstractElement *element : this->element_vec){element->accept(visitor); // 實際上 調用 具體元素類的 接收方法}}private:// 抽象元素指針(實際上指向一個具體元素對象)的集合vector<AbstractElement *> element_vec;
};// 客戶端
int main()
{// 具體元素對象ConcreteElementA element_A;ConcreteElementB element_B;// 對象結構對象ObjectStructure object_structure;object_structure.add_element(&element_A); // 對象結構 添加元素object_structure.add_element(&element_B);// 具體訪問者對象ConcreteVisitor visitor;object_structure.accept(&visitor); // 對象結構 接收 訪問者的訪問// 訪問過程:// object_structure.accept(&visitor); ->// 對象結構類的 接收方法,發送參數是 訪問者對象(對象結構 需要 訪問者訪問)// element->accept(visitor); ->// 具體元素類的 接收方法,發送參數是 訪問者對象(元素 需要 訪問者訪問)// visitor->visit_element_A(this);// 具體訪問者類的 訪問方法,發送參數是 具體元素對象(元素 允許 訪問者訪問)// element->operation_A();// 具體訪問者類的 操作方法(訪問者 訪問 元素)// 具體訪問者新對象ConcreteVisitorNew visitor_new;object_structure.accept(&visitor_new);return 0;
}
/*
輸出:
ConcreteVisitor visits ConcreteElementA
ConcreteElementA operation
ConcreteVisitor ConcreteElementB
ConcreteElementB operation
ConcreteVisitorNew visits ConcreteElementA
ConcreteElementA operation
ConcreteVisitorNew ConcreteElementB
ConcreteElementB operation
*/

總結

中介者和訪問者模式(行為型設計模式)的 C++ 代碼示例模板。


參考資料

  • 行為型設計模式總結_設計模式行為型模式的設計與實現心得體會-CSDN博客

作者的話

  • 感謝參考資料的作者/博主
  • 作者:夜悊
  • 版權所有,轉載請注明出處,謝謝~
  • 如果文章對你有幫助,請點個贊或加個粉絲吧,你的支持就是作者的動力~
  • 文章在描述時有疑惑的地方,請留言,定會一一耐心討論、解答
  • 文章在認識上有錯誤的地方, 敬請批評指正
  • 望讀者們都能有所收獲

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

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

相關文章

HarmonyOS應用程序包-(下)

HarmonyOS應用程序包-(下) 1.多HAP的開發調試與發布部署流程 多HAP的開發調試與發布部署流程如下圖所示。 圖1 多HAP的開發調試與發布部署流程 開發 開發者通過DevEco Studio工具按照業務的需要創建多個Module&#xff0c;在相應的Module中完成自身業務的開發。 調試 通過…

C++歸并排序詳解以及代碼實現

1. 介紹 歸并排序&#xff08;Merge Sort&#xff09;是一種采用分治法&#xff08;Divide and Conquer&#xff09;策略的排序算法。該算法首先將已有序的子序列合并&#xff0c;得到完全有序的序列。在歸并排序中&#xff0c;合并操作是將兩個有序表合并成一個有序表的過程。…

echarts實現七天天氣預報

效果圖 實現代碼 const imglist {"晴": data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADMAAAAzCAYAAAA6oTAqAAAAAXNSR0IArs4c6QAAByJJREFUaEO9Wl1rFGcUfs67u/nYbOIXJlGopBTx27aQWGOwSMS75sao2BtBQVD/gWCJouA/sIWCBW8M1nqjd1IplW5DYqLWEUoSi9iEjHaJmaz2d05ZWd2Nj…

KingbaseV8R6單實例定時全量備份步驟

此場景為單機數據庫節點內部備份&#xff0c;方便部署和操作&#xff0c;但備份REPO與數據庫實例處于同一個物理主機&#xff0c;冗余度較低。 前期準備 配置ksql免密登錄(必須) 在Kingbase數據庫運行維護中&#xff0c;經常用到ksql工具登錄數據庫&#xff0c;本地免密登錄…

基于OpenCV的圖像顏色與形狀識別的原理

基于 OpenCV 的圖像顏色與形狀識別是通過以下原理實現的&#xff1a; 圖像預處理&#xff1a;首先&#xff0c;將彩色圖像轉換為灰度圖像。這樣做是因為在灰度圖像中&#xff0c;每個像素只有一個顏色通道&#xff0c;可以更方便地進行后續處理。 閾值分割&#xff1a;對灰度圖…

Linux系統編程(六):進程(下)

參考引用 UNIX 環境高級編程 (第3版)嵌入式Linux C應用編程-正點原子 1. 進程與程序 1.1 main() 函數由誰調用&#xff1f; C 語言程序總是從 main 函數開始執行int main(void) int main(int argc, char *argv[]) // 如果需要向應用程序傳參&#xff0c;則選擇該種寫法操作系…

C++ 比 C語言增加的新特性 2

1.C新增了帶默認值參數的函數 1.1 格式 格式&#xff1a;返回值 函數名&#xff08;參數1初始值1&#xff0c;..........&#xff09;{} 例如&#xff1a;void function&#xff08;int a10&#xff09;{} 調用&#xff1a;不需要更改參數的值&#xff1a;function&#x…

基于SSM和微信小程序的高校體育場管理系統

文章目錄 項目介紹主要功能截圖:部分代碼展示設計總結項目獲取方式?? 作者主頁:超級無敵暴龍戰士塔塔開 ?? 簡介:Java領域優質創作者??、 簡歷模板、學習資料、面試題庫【關注我,都給你】 ??文末獲取源碼聯系?? 項目介紹 基于SSM和微信小程序的高校體育場管理系…

文本編輯器:Sublime Text (安裝+漢化)

下載 Sublime Text - Text Editing, Done Righthttps://www.sublimetext.com/Sublime Text官網 支持mac&#xff0c;Linux&#xff0c;Windows 安裝 選擇安裝路徑 next install 選擇安裝位置安裝就行了 漢化 進入了主界面按 CTRLshiftp 輸入install 選擇第一個 彈窗就按確…

服務器擴容未生效、不成功:解決方法

記一次解決服務器擴容未生效的解決辦法 老板&#xff1a;失憶啊&#xff0c;我花錢給服務器擴容了10000000G&#xff0c;但是數據庫和mq都還是用不了&#xff0c;到底是不是服務器磁盤滿了&#xff0c;你到底有沒有查一下什么原因導致服務用不了啊。 失憶&#xff1a;老板您確…

概率論1:下象棋問題(3.5)

每日小語 時刻望著他人的眼色行事&#xff0c;是騰飛不了的。自己怎么想就積極地去做&#xff0c;這是需要膽量的。——廣中平佑 題目 甲、乙二人下象棋&#xff0c; 每局甲勝的概率為a,乙勝的概率為b. 為簡化問題&#xff0c;設沒有和局的情況&#xff0c;這意味著a b1. 設想…

VR全景對普通人的生活有哪些好處?

許多普通人對VR全景還全然沒有概念&#xff0c;這是因為VR全景雖然一直在快速發展&#xff0c;但目前為止也不過幾年而已&#xff0c;但這發展的幾年同樣為我們普通人的生活帶來了切實的改變和便利。VR全景技術為人們帶來了沉浸感和真實感的體驗&#xff0c;讓我們感受到迥異于…

第十四章 集合(Set)

一、Set 接口&#xff08;P518&#xff09; 1. Set 接口基本介紹 &#xff08;1&#xff09;無序&#xff08;添加和取出的順序不一致&#xff09;&#xff0c;沒有索引。 &#xff08;2&#xff09;不允許重復元素&#xff0c;所以最多包含一個 null。 2. Set 接口的常用方法…

數據結構:KMP算法

1.何為KMP算法 KMP算法是由Knuth、Morris和Pratt三位學者發明的&#xff0c;所以取了三位學者名字的首字母&#xff0c;叫作KMP算法。 2.KMP的用處 KMP主要用于字符串匹配的問題&#xff0c;主要思想是當出現字符串不匹配時&#xff0c;我們可以知道一部分之前已經匹配過的的文…

【期刊周報1】醫學好刊(SCI/SSCI/EI),含Top,領域廣,接收快!

為了向廣大學者朋友提供更優質的選刊服務&#xff0c;提高選刊質量&#xff0c;我處現開設周報專欄&#xff0c;以羅列我處合作的優質期刊~ 本期&#xff0c;小編給大家推薦的是醫學領域相關的熱門期刊&#xff0c;接收領域廣&#xff0c;無預警&#xff0c;且在最新檢索目錄內…

Python遙感影像深度學習指南(2)-在 PyTorch 中創建自定義數據集和加載器

在上一篇 文章中,我們Fast.ai 在衛星圖像中檢測云輪廓,檢測物體輪廓被稱為語義分割。雖然我們用幾行代碼就能達到 96% 的準確率,但該模型無法考慮數據集中提供的所有輸入通道(紅、綠、藍和近紅外)。問題在于,深度學習框架(如 Keras、Fast.ai 甚至 PyTorch)中的大多數語…

油煙凈化器如何做到高效凈化?科技力量,清新餐飲生活

我最近分析了餐飲市場的油煙凈化器等產品報告&#xff0c;解決了餐飲業廚房油膩的難題&#xff0c;更加方便了在餐飲業和商業場所有需求的小伙伴們。 油煙凈化器的出現&#xff0c;為我們的餐飲生活注入了一抹清新的色彩。然而&#xff0c;它究竟是如何工作的&#xff1f;為何能…

【開題報告】基于SSM的健康飲食系統設計與實現

1.研究背景 如今&#xff0c;隨著人們生活水平的提高和健康意識的增強&#xff0c;越來越多的人開始關注自己的飲食習慣&#xff0c;并希望通過合理的飲食來維持身體健康。然而&#xff0c;對于許多人來說&#xff0c;了解和選擇合適的飲食方式并不容易。傳統的飲食指導往往比…

【并發設計模式】聊聊Immutability模式利用不變性解決并發問題

上一篇文章&#xff0c;我們介紹了如何利用二階段停止協議進行優雅停止線程和線程池&#xff0c;本篇介紹在并發編程中數據安全性&#xff0c;我們知道針對于數據的操作&#xff0c;讀和寫(添加、刪除、修改), 在并發線程讀寫的時候&#xff0c;變量不加鎖的情況下&#xff0c;…

redis哨兵+redis主從復制(在虛擬機centos的docker下)

1.安裝docker Docker安裝(CentOS)簡單使用-CSDN博客 2.redis主從復制 redis主從復制(在虛擬機centos的docker下)-CSDN博客 3.編輯3個redis配置 cd /etc mkdir redis-sentinel cd redis-sentinel/ wget http://download.redis.io/redis-stable/sentinel.confcp sentinel.co…