文章目錄
- 前言
- 代碼倉庫
- 中介者模式(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博客
作者的話
- 感謝參考資料的作者/博主
- 作者:夜悊
- 版權所有,轉載請注明出處,謝謝~
- 如果文章對你有幫助,請點個贊或加個粉絲吧,你的支持就是作者的動力~
- 文章在描述時有疑惑的地方,請留言,定會一一耐心討論、解答
- 文章在認識上有錯誤的地方, 敬請批評指正
- 望讀者們都能有所收獲