中介者模式
在软件构建过程中,经常出现多个对象相互关联交互的情况,对象之间常常会维持一种复杂的引用关系,如果遇到需求变更,这种引用关系会面临不断地变化(不稳定)。在这种情况下,使用一个中介对象来封装一系列的对象交互(封装变化),使得各对象不需要显式的相互依赖(编译时依赖->运行时依赖),达到松耦合的目的(管理变化)。
代码如下:以租房为例(此处对象只有两个:租房者和房东)
#pragma once
#ifndef MEDIATOR_H
#define MEDIATOR_H
#include<string>
#include<vector>
#include<iostream>
using namespace std;
class Mediator;
//抽象人
class Person {
public:
Person(Mediator* m):mediator(m){}
virtual void send(const string&) = 0;
virtual void receive(const string&) = 0;
virtual ~Person(){}
protected:
Mediator* mediator;
};
//抽象中介
class Mediator {
public:
virtual void setObjectA(Person* ob1) = 0;
virtual void setObjectB(Person* ob1) = 0;
virtual void distribute(Person* person, const string& msg) = 0;
virtual ~Mediator() {}
};
//租房者
class Renter :public Person {
public:
Renter(Mediator* m) :Person(m) {}
void send(const string& msg) override{
mediator->distribute(this, msg);//通过中介者传消息
}
void receive(const string& msg)override {
cout << "Renter received msg: " << msg << endl;
}
};
//房东
class Landlord :public Person {
public:
Landlord(Mediator* m) :Person(m) {}
void send(const string& msg) override {
mediator->distribute(this, msg);
}
void receive(const string& msg)override {
cout << "Landlord received msg: " << msg << endl;
}
};
//房屋中介
class HouseMediator :public Mediator {
public:
void setObjectA(Person* ob1) {
p1 = ob1;
}
void setObjectB(Person* ob2) {
p2 = ob2;
}
void distribute(Person* person, const string& msg) {
if (person == p1)//租房者给房东发消息
p2->receive(msg);
else
p1->receive(msg);
}
private:
Person* p1;//租房者
Person* p2;//房东
};
#endif // !MEDIATOR_H
测试代码如下:
#include<iostream>
#include"mediator.h"
using namespace std;
int main()
{
Mediator* mediator = new HouseMediator();
Person* p1 = new Renter(mediator);
Person* p2 = new Landlord(mediator);
mediator->setObjectA(p1);
mediator->setObjectB(p2);
p1->send("I want rent house,the price is 800 yuan");
p2->send("I heve a house to rent for 1000 yuan per month, 70");
delete mediator, p1, p2;
return 0;
}
运行结果如下:
当有2个以上的对象时,代码如下:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class Mediator;
class Colleague
{
public:
Colleague(Mediator* const m, const unsigned int i) :
mediator(m), id(i) {}
virtual ~Colleague() {}
unsigned int getID()
{
return id;
}
virtual void send(const string&) = 0;
virtual void receive(const string&) = 0;
protected:
Mediator* mediator;
unsigned int id;
};
class ConcreteColleague : public Colleague
{
public:
ConcreteColleague(Mediator* const m, const unsigned int i) :
Colleague(m, i) {}
~ConcreteColleague() {}
void send(const string& msg);
void receive(const string& msg)
{
std::cout << "Message '" << msg << "' received by Colleague " << id << std::endl;
}
};
class Mediator
{
public:
virtual ~Mediator() {}
virtual void add(Colleague* const c) = 0;
virtual void distribute(Colleague* const sender, std::string msg) = 0;
protected:
Mediator() {}
};
class ConcreteMediator : public Mediator
{
public:
~ConcreteMediator()
{
for (unsigned int i = 0; i < colleagues.size(); i++)
{
delete colleagues[i];
}
colleagues.clear();
}
void add(Colleague* const c)
{
colleagues.emplace_back(c);
}
//执行中介者传消息
void distribute(Colleague* const sender, std::string msg)
{
for (unsigned int i = 0; i < colleagues.size(); i++)
{
if (colleagues.at(i)->getID() != sender->getID())
{
colleagues.at(i)->receive(msg);
}
}
}
private:
std::vector<Colleague*> colleagues;
};
void ConcreteColleague::send(const string& msg)
{
std::cout << "Message '" << msg << "' sent by Colleague " << id << std::endl;
mediator->distribute(this, msg);//中介者传消息
}
int main()
{
Mediator* mediator = new ConcreteMediator();
Colleague* c1 = new ConcreteColleague(mediator, 1);
Colleague* c2 = new ConcreteColleague(mediator, 2);
Colleague* c3 = new ConcreteColleague(mediator, 3);
mediator->add(c1);
mediator->add(c2);
mediator->add(c3);
c1->send("Hi!");
c3->send("Hello!");
delete mediator;
return 0;
}
运行结果: