【设计模式】——中介者模式(Mediator Pattern)

目录

引言

一、中介者模式的基本概念

核心思想

中介者模式结构

UML图

应用场景

二、中介者模式的优点与缺点

优点

缺点

三、C++实现中介者模式

1. 定义中介者接口

2. 定义具体中介者

3. 定义同事接口及具体实现

4. 客户端代码

5. 输出结果

四、总结


 

引言

在软件设计中,设计模式是解决常见问题的最佳实践。中介者模式(Mediator Pattern)是一种对象行为型模式,主要用于降低系统中对象之间的耦合度,通过引入一个中介者来封装对象之间的交互,使得对象之间的交互更加灵活和可扩展。本文将详细介绍中介者模式在C++中的实现方式及其应用场景。

一、中介者模式的基本概念

中介者模式定义了一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,是迪米特法则(最少知识原则)的典型应用。在中介者模式中,各个对象不再直接相互引用和通信,而是通过中介者来进行间接通信。

核心思想

中介者模式的核心思想是通过引入一个中介对象来封装一系列对象之间的交互,使得各个对象之间不需要显式地相互引用,从而降低了对象之间的耦合度。中介者对象管理并协调这些对象之间的交互,使得系统结构更加清晰,易于维护和扩展。

中介者模式结构

中介者模式主要由以下几个部分组成:

  1. Mediator(抽象中介者):定义了一个接口,用于与各个同事对象通信,并管理各个同事对象之间的关系。通常包含一些用于处理各种交互事件的方法。

  2. ConcreteMediator(具体中介者):实现了中介者接口,负责实现各个同事对象之间的通信逻辑。它通常会维护一个对各个同事对象的引用,并协调它们的交互。

  3. Colleague(抽象同事类):定义了一个接口,用于与中介者进行通信。通常包含一个发送消息的方法和一个接收消息的方法。

  4. ConcreteColleague(具体同事类):实现了同事对象接口,是真正参与到交互中的对象。它将自己的消息发送给中介者,由中介者转发给其他同事对象。

UML图

95e5755a87834f5eab61d73553ee09d8.png

应用场景

中介者模式适用于以下场景:

  1. 对象间存在复杂的网状结构关系:当系统中多个类相互耦合,形成网状结构时,使用中介者模式可以将这种网状结构转换为星形结构,从而降低系统复杂度。

  2. 需要改变对象间的交互方式:如果系统中对象之间的交互方式经常变化,使用中介者模式可以封装这些交互逻辑,使得对象之间的交互更加灵活。

  3. 多人协作或通信:如聊天室、多人游戏等场景,中介者模式可以简化对象之间的通信过程。

二、中介者模式的优点与缺点

优点

  1. 降低复杂度:将多个对象间的一对多关系转换为一对一关系,降低了程序的复杂程度。

  2. 解耦:实现了类之间的解耦操作,对象之间不再需要相互引用,只需通过中介者进行交互。

  3. 提高可复用性:由于对象之间的交互被封装在中介者中,因此可以独立地改变对象之间的交互方式,而不需要修改对象本身的代码。

  4. 符合迪米特原则:对象只需知道中介者,不需要知道其他对象,降低了系统的耦合度。

缺点

  1. 中介者复杂性:当系统中对象数量较多时,中介者可能会变得庞大和复杂,难以维护。

  2. 中介者成为系统瓶颈:如果中介者出现问题,可能会影响到整个系统的正常运行。

  3. 过度使用:在不需要中介者模式的情况下使用中介者模式,可能会增加系统的复杂性。

三、C++实现中介者模式

1. 定义中介者接口

首先,我们定义一个中介者接口,该接口包含用于通信的方法。

#include <string>  
#include <vector>  
#include <iostream>

class Colleague; // 前置声明  

// 中介者接口
class Mediator {
public:
    virtual ~Mediator() {}
    virtual void Notify(Colleague* colleague, const std::string& message) = 0;
};

2. 定义具体中介者

接下来,我们实现一个具体的中介者类,该类将负责协调同事对象之间的交互。

// 具体中介者
class ConcreteMediator : public Mediator {
private:
    std::vector<Colleague*> colleagues;

public:
    void Register(Colleague* colleague) {
        colleagues.push_back(colleague);
    }

    void Notify(Colleague* sender, const std::string& message) override {
        for (auto colleague : colleagues) {
            if (colleague != sender) {
                colleague->Receive(message);
            }
        }
    }
};

3. 定义同事接口及具体实现

然后,我们定义同事类的接口和具体实现。

// 同事接口及具体实现
class Colleague {
protected:
    Mediator* mediator;

public:
    Colleague(Mediator* mediator) : mediator(mediator) {}

    virtual ~Colleague() {}

    virtual void Send(const std::string& message) = 0;
    virtual void Receive(const std::string& message) = 0;
};

class ConcreteColleague : public Colleague {
private:
    std::string name;

public:
    ConcreteColleague(Mediator* mediator, const std::string& name) : Colleague(mediator), name(name) {}

    void Send(const std::string& message) override {
        mediator->Notify(this, message);
    }

    void Receive(const std::string& message) override {
        std::cout << name << " received: " << message << std::endl;
    }
}; 

4. 客户端代码

最后,我们编写客户端代码来演示中介者模式的使用。


int main() {
    ConcreteMediator mediator;

    ConcreteColleague alice(&mediator, "Alice");
    ConcreteColleague bob(&mediator, "Bob");
    ConcreteColleague charlie(&mediator, "Charlie");

    mediator.Register(&alice);
    mediator.Register(&bob);
    mediator.Register(&charlie);

    alice.Send("Hello, everyone!");

    return 0;
}

5. 输出结果

因为 alice 发送了消息,而 bob 和 charlie 接收到了这条消息(alice 自己不会接收自己发送的消息)。

Bob received: Hello, everyone!  
Charlie received: Hello, everyone!

四、总结

中介者模式是一种非常有用的设计模式,它通过引入中介者来降低对象之间的耦合度,使得对象之间的交互更加灵活和可扩展。在C++中实现中介者模式时,需要注意中介者的职责不应过重,以避免造成系统复杂度的增加。同时,中介者模式也适用于多种应用场景,如事件处理系统、聊天室或消息传递系统等。通过合理地应用中介者模式,可以提高软件系统的可维护性和可扩展性。

 

  • 18
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

J^T

谢谢帅哥/美女

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值