中介者和访问者模式(行为型设计模式)的 C++ 代码示例模板
2023-12-25 10:34:50
前言
中介者和访问者模式(行为型设计模式)的 C++ 代码示例模板。
代码仓库
中介者模式(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++ 代码示例模板。
参考资料
作者的话
- 感谢参考资料的作者/博主
- 作者:夜悊
- 版权所有,转载请注明出处,谢谢~
- 如果文章对你有帮助,请点个赞或加个粉丝吧,你的支持就是作者的动力~
- 文章在描述时有疑惑的地方,请留言,定会一一耐心讨论、解答
- 文章在认识上有错误的地方, 敬请批评指正
- 望读者们都能有所收获
文章来源:https://blog.csdn.net/m0_62083249/article/details/135176702
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!