设计模式——15.中介者模式

中介者模式(Mediator)

中介者模式(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();
	}
}

运行实例:

MediatorRes

中介者模式的优点及缺点

优点:

使用中介者模式之后,使用的类无论是从类外部获取信息还是向外部传递信息,都通过中介者类来完成;当需要做出一些修改时,可以大大减小后期修改维护时的难度。

缺点:

当过多的类都通过中介者进行沟通时,中介者类中会出现操作接口爆炸的情况,此时,我们可以适当搭配其他设计模式来减轻中介者类的负担。

REF

书籍:

设计模式与游戏开发、大话设计模式

GitHub:

https://github.com/me115/design_patterns

posted @ 2018-12-16 19:29  SylvanYan  阅读(201)  评论(0编辑  收藏  举报
TOP