中介者模式

  • 一、概述
  • 二、结构
  • 三、实例
  • 四、优缺点
  • 五、适用场景


一、概述

描述:在租房时,租客需要联系中介,中介通过联系房主,构建起联系关系。

定义:用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

二、结构

  1. 抽象中介者(Mediator)角色:它是中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法;定义一个接口用于与各同事对象通信;
  2. 具体中介者(ConcreteMediator)角色:实现中介者接口,定义一个 List 来管理同事对象,协调各个同事角色之间的交互关系,了解并维护它的各个同事,因此它依赖于同事角色;
  3. 抽象同事类(Colleague)角色:定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能;
  4. 具体同事类(Concrete Colleague)角色:是抽象同事类的实现者,当需要与其他同事对象通信/交互时,与中介者通信即可,而后由中介者对象负责后续的交互;因此每一个具体同事类需要知道中介者对象,而不需要了解其他同事类的情况。

三、实例

//
//中介者模式
//关键代码:对象 Colleague 之间的通信封装到一个类中单独处理
//

#include<iostream>
#include<string>
#include<memory>
#include<vector>
using namespace std;

class Mediator;

//抽象人
class Person {
protected:
  shared_ptr<Mediator> m_mediator; //中介
public:
    Person(const shared_ptr<Mediator> pMediator)
        : m_mediator(pMediator) {}

    virtual ~Person() = default;//虚析构函数

    //向中介发送信息
    virtual void SendMessage(const string& message) = 0;

    //从中介获取信息
    //message 中介向该对象发送的信息/从中介获取的信息
    virtual void GetMessage(const string& message) = 0;
};

//抽象中介机构
class Mediator {
public:
    virtual ~Mediator() = default;

    //由于后面this指针的原因,此处未采用智能指针
    virtual void Send(string message, const Person* from_person) const = 0;

    virtual void Register(shared_ptr<Person> pPerson) = 0;
};

//租房者A
class RenterA : public Person {
public:
    RenterA(const shared_ptr<Mediator> mediator) : Person(mediator) {}

    void SendMessage(const string& message) override {
        m_mediator->Send(message, this);
    }

    void GetMessage(const string& message) override {
       cout << "租房者A收到信息" << message << endl;
    }
};

//租房者B
class RenterB : public Person {
public:
    RenterB(const shared_ptr<Mediator> mediator) : Person(mediator) {}

    void SendMessage(const string& message) override {
        m_mediator->Send(message, this);
    }

    void GetMessage(const string& message) override {
       cout << "租房者B收到信息" << message <<endl;
    }
};


//房东
class Landlord : public Person {
public:
    Landlord(const shared_ptr<Mediator> mediator) : Person(mediator) {}

    void SendMessage(const string& message) override {
        m_mediator->Send(message, this);
    }

    void GetMessage(const string& message) override {
       cout << "房东收到信息:" << message << endl;
    }
};

//房屋中介
class HouseMediator : public Mediator {
private:
    //也可以采用多个list,将多个房东放入一个list,将多个求租者放入一个list
    vector<shared_ptr<Person>> m_pPersonList;
public:
    void Register(const shared_ptr<Person> pPerson) override {
        //没有添加该同事,则添加进去
        auto iter = m_pPersonList.begin();
        for (; iter != m_pPersonList.end(); ++iter) {
            if (*iter == pPerson)
                break;
        }

        if (iter == m_pPersonList.end())
            m_pPersonList.emplace_back(pPerson);

    }

    void Send(string message, const Person* from_person) const override {
        //接收消息的对象为该对象的对应对象
        //
        for (const auto item : m_pPersonList) {
            //此处采用typeid,而非直接判断指针是否相等为同一个对象.
            // 具体何种方式,一般区别不大,视情况而定
            if (typeid(*item.get()) != typeid(*from_person))
                //if( item.get() != from_person)
                item->GetMessage(message);
        }
    }
};

//客户端
int main() {
   // Mediator* pHouseMediator = new HouseMediator();

   shared_ptr<Mediator> pHouseMediator = make_shared<HouseMediator>();
  
   /*
   多态的要素:子类重写父类的成员函数(override); 父类指针指向子类对象;
   利用父类指针调用重写的成员函数。
   父类指针指向子类对象;利用父类指针调用重写的成员函数。
   */ 

   
    shared_ptr<Person> pRenterA = make_shared<RenterA>(pHouseMediator);
    shared_ptr<Person> pRenterB = make_shared<RenterB>(pHouseMediator);
    shared_ptr<Person> pLandlord =make_shared<Landlord>(pHouseMediator);

    pHouseMediator->Register(pRenterA);
    pHouseMediator->Register(pRenterB);
    pHouseMediator->Register(pLandlord);

    pLandlord->SendMessage("出租房");//所有的求租者将会收到该消息

    cout << string(50, '-') << std::endl;

    pRenterA->SendMessage("租房");//所有的房东将会收到该消息

    return 0;

    
}

mediapipe Hands模型中有CNN吗_c++

四、优缺点

优点:

  1. 降低了类的复杂度,将一对多关联转化成了一对一的关联,提高了系统的灵活性,使得系统易于维护和扩展;
  2. .降低了对象之间的耦合性,使得对象易于独立地被复用;
  3. 符合迪米特原则:只与你最直接的朋友交流。

缺点:

  1. 当同事类太多时,中介者的职责将很大,它会变得复杂而庞大,以至于系统难以维护。

五、适用场景

  1. 对象和其他对象紧密耦合以致难以对其进行修改时,可使用中介者模式。
  2. 当组件因过于依赖其他组件而无法在不同应用中复用时,可使用中介者模式。
  3. 为了能在不同情景下复用一些基本行为,导致你需要被迫创建大量组件子类时,可使用中介者模式。