中介者和访问者模式(行为型设计模式)的 C++ 代码示例模板

文章目录

  • 前言
  • 代码仓库
  • 中介者模式(Mediator)
  • 访问者模式(Visitor)
  • 总结
  • 参考资料
  • 作者的话

前言

中介者和访问者模式(行为型设计模式)的 C++ 代码示例模板。


代码仓库

  • yezhening/Programming-examples: 编程实例 (github.com)
  • Programming-examples: 编程实例 (gitee.com)

中介者模式(Mediator)

结构

  • 抽象同事类
  • 抽象中介者类
  • 具体中介者类 (协调交互 的对象)
  • 具体同事类 (需要交互 的对象)
  • 抽象同事类 封装 抽象中介者指针(实际上指向一个具体中介者对象)(同事 需要认识 中介者)、发送消息方法 和 接收消息方法
  • 抽象中介者类 封装 转发消息方法
  • 具体中介者类 封装 抽象同事指针(实际上指向一个具体同事对象)(中介者 需要认识 同事)
  • 具体中介者类 重写 转发消息方法 (形式上 调用 具体中介者类的 转发消息方法,实际上 调用 具体同事类的 接收消息方法(中介者 转发消息,同事 接收消息))
  • 具体同事类 重写 发送消息方法 (形式上 调用 具体同事类的 发送消息方法,实际上 调用 具体中介者类的 转发消息方法(当前同事 发送消息,委托 中介者 转发消息)) 和 接收消息方法

代码

#include 
#include 

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 
#include 

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博客

作者的话

  • 感谢参考资料的作者/博主
  • 作者:夜悊
  • 版权所有,转载请注明出处,谢谢~
  • 如果文章对你有帮助,请点个赞或加个粉丝吧,你的支持就是作者的动力~
  • 文章在描述时有疑惑的地方,请留言,定会一一耐心讨论、解答
  • 文章在认识上有错误的地方, 敬请批评指正
  • 望读者们都能有所收获

你可能感兴趣的:(设计模式,中介者模式,访问者模式,行为型设计模式,设计模式,C++)