文章目录
- 前言
- 代码仓库
- 中介者模式(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博客
作者的话
- 感谢参考资料的作者/博主
- 作者:夜悊
- 版权所有,转载请注明出处,谢谢~
- 如果文章对你有帮助,请点个赞或加个粉丝吧,你的支持就是作者的动力~
- 文章在描述时有疑惑的地方,请留言,定会一一耐心讨论、解答
- 文章在认识上有错误的地方, 敬请批评指正
- 望读者们都能有所收获