中介者模式(Mediator)
中介者模式(Mediator)简介:
用一个中介对象来封装一系列对象的交互。中介者模式是各个对象不再显式的相互引用,从而降低耦合,并且可以独立的改变各个对象之间的交互。
中介者模式结构:
C++代码
Colleague抽象类及其具体实现类:
//file: Colleague.h
#pragma once
#include "Mediator.h"
#include <string>
using namespace std;
class Colleague
{
public:
Colleague();
virtual ~Colleague();
virtual void receive(string msg);
virtual void request(int num , string msg);
void setMediator(Mediator * pm);
protected:
Mediator * m_Pm;
};
class ConcreteColleagueA : public Colleague
{
public:
ConcreteColleagueA();
virtual ~ConcreteColleagueA();
virtual void request(int num, string msg);
virtual void receive(string msg);
};
class ConcreteColleagueB : public Colleague
{
public:
ConcreteColleagueB();
virtual ~ConcreteColleagueB();
void request(int num, string msg);
void receive(string msg);
};
//file: Colleague.cpp
#include "pch.h"
#include "Colleague.h"
#include <iostream>
using namespace std;
///Colleague
Colleague::Colleague() {}
Colleague::~Colleague() {}
void Colleague::setMediator(Mediator *pm)
{
m_Pm = pm;
}
void Colleague::request(int num , string msg) {}
void Colleague::receive(string msg) {}
///ConcreteColleagueA
ConcreteColleagueA::ConcreteColleagueA() {}
ConcreteColleagueA::~ConcreteColleagueA() {}
void ConcreteColleagueA::request(int num, string msg)
{
m_Pm->operation(num, msg);
}
void ConcreteColleagueA::receive(string msg)
{
cout << "ConcreteColleague A Receive the msg : " << msg << endl;
}
///ConcreteColleagueB
ConcreteColleagueB::ConcreteColleagueB() {}
ConcreteColleagueB::~ConcreteColleagueB() {}
void ConcreteColleagueB::request(int num, string msg)
{
m_Pm->operation(num, msg);
}
void ConcreteColleagueB::receive(string msg)
{
cout << "ConcreteColleagueB Receive the msg :" << msg << endl;
}
Mediator中介者类及其具体实现类:
//file: Mediator.h
#pragma once
#include <string>
#include <map>
using namespace std;
class Colleague;
class Mediator
{
public:
Mediator();
virtual ~Mediator();
virtual void operation(int num , std::string msg);
virtual void registered(int num , Colleague * pc);
};
class ConcreteMediator : public Mediator
{
public:
ConcreteMediator();
virtual ~ConcreteMediator();
void operation(int num, string msg);
void registered(int num, Colleague * pc);
private:
map<int, Colleague *> m_colleagueMap;
};
//file: Mediator.h
#include "pch.h"
#include "Mediator.h"
#include "Colleague.h"
#include <iostream>
using namespace std;
///Mediator
Mediator::Mediator() {}
Mediator::~Mediator() {}
void Mediator::operation(int num, string msg) {}
void Mediator::registered(int num, Colleague * pc) {}
///ConcreteMediator
ConcreteMediator::ConcreteMediator() {}
ConcreteMediator::~ConcreteMediator() {}
void ConcreteMediator::registered(int num, Colleague * pc)
{
map<int, Colleague *> ::const_iterator iter = m_colleagueMap.find(num);
if (iter == m_colleagueMap.end())
{
m_colleagueMap.insert(make_pair(num, pc));
pc->setMediator(this);
}
}
void ConcreteMediator::operation(int num, string msg)
{
map<int, Colleague *>::const_iterator iter = m_colleagueMap.find(num);
if (iter == m_colleagueMap.end())
{
cout << "This Colleague is not found ." << endl;
return;
}
Colleague* pc = iter->second;
pc->receive(msg);
}
客户端代码:
//file: MediatorPattern.cpp : This file contains the 'main' function. Program execution begins and ends there.
#include "pch.h"
#include "Colleague.h"
#include "Mediator.h"
#include <iostream>
using namespace std;
int main()
{
ConcreteMediator * m_pm = new ConcreteMediator();
ConcreteColleagueA * m_pcA = new ConcreteColleagueA();
ConcreteColleagueB * m_pcB = new ConcreteColleagueB();
m_pm->registered(1,m_pcA);
m_pm->registered(2,m_pcB);
m_pcA->request(2,"Are you OK ?");
m_pcB->request(1,"Ennnnnn");
delete m_pm, m_pcA, m_pcB;
return 0;
}
C#代码
Colleague抽象类及其具体实现类:
public abstract class Colleague
{
protected Mediator mediator = null;
public Colleague(Mediator mediator)
{
this.mediator = mediator;
}
public abstract void request(int num , string msg);
public abstract void receive(string msg);
}
public class Colleague1 : Colleague
{
public Colleague1(Mediator mediator) : base(mediator) { }
public override void receive(string msg)
{
Console.WriteLine("Colleague1 got the msg : " + msg);
}
public override void request(int num, string msg)
{
mediator.sendMsg(2, msg);
}
}
public class Colleague2 : Colleague
{
public Colleague2(Mediator mediator) : base(mediator) { }
public override void receive(string msg)
{
Console.WriteLine("Colleague2 got the msg : " + msg);
}
public override void request(int num, string msg)
{
mediator.sendMsg(1, msg);
}
}
Mediator中介者类及其具体实现类:
public abstract class Mediator
{
public abstract void sendMsg(int num, string msg);
}
public class ConcreteMediator : Mediator
{
Dictionary<int, Colleague> m_ColleagueDict = new Dictionary<int, Colleague>();
public void Register(int num ,Colleague c)
{
if (m_ColleagueDict.ContainsKey(num))
Console.WriteLine("Error: The Key is Exits .");
m_ColleagueDict.Add(num ,c);
}
public override void sendMsg(int num, string msg)
{
Colleague c = null;
if (!m_ColleagueDict.TryGetValue(num, out c))
Console.WriteLine("Error : Not found this colleague!");
c.receive(msg);
}
}
客户端测试代码:
class Program
{
static void Main(string[] args)
{
ConcreteMediator mediator = new ConcreteMediator();
Colleague1 colleague1 = new Colleague1(mediator);
Colleague2 colleague2 = new Colleague2(mediator);
mediator.Register(1,colleague1);
mediator.Register(2,colleague2);
colleague1.request(2,"Are you OK?");
colleague2.request(1,"Ennnnnnn");
Console.ReadKey();
}
}
运行实例:
中介者模式的优点及缺点
优点:
使用中介者模式之后,使用的类无论是从类外部获取信息还是向外部传递信息,都通过中介者类来完成;当需要做出一些修改时,可以大大减小后期修改维护时的难度。
缺点:
当过多的类都通过中介者进行沟通时,中介者类中会出现操作接口爆炸的情况,此时,我们可以适当搭配其他设计模式来减轻中介者类的负担。
REF
书籍:
设计模式与游戏开发、大话设计模式
GitHub: