设计模式系列5-----C++实现中介者模式(Mediator Pattern)

什么是中介者模式?

      Mediator Pattern Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.

      换言之,将各个类与其他类交互的逻辑单独出来放在封装在一个Mediator类里面,它负责各个类之间的交互,这样的好处是各个类(同事类)可以专注于自己的职责,即高内聚。同时降低与其他类的联系,即低耦合。

类图结构:

      中介者模式常用于UI设计,类图如下:

       当然,同事类不一定是继承自同一祖先。

 

Example:

      例子描述的是Alarm、Calendar、CoffeePot三个类之间的交互通过Mediator来完成,关系图如下:

image

 

colleague.h如下:

#ifndef __COLLEAGUE_H__
#define __COLLEAGUE_H__

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

class Mediator;

class Calender
{
public:
	Calender(Mediator* pMediator);

	void addEvent(int timeInSeconds, std::string desc);

	bool checkEvent( int timeInSeconds );

private:
	Mediator* m_pMediator;
	map<int, string> m_mapCalender;
};

class Alarm
{
public:
	Alarm(Mediator* pMediator);

	void setTime(int nTime);

	int getTime();

	void setTimer(int timeInseconds);

	void start();

	void stop();

	bool isThereAlarm( int tm );

private:
	int m_nTime;
	vector<int> times;
	Mediator* m_pMediator;
};

class CoffeePot
{
public:
	CoffeePot(Mediator* pMediator, int nStart = 100000);

	void cook(int nStart);
	void ready( int tm );
	bool isReady( int tm );
private:
	int m_nStart;
	Mediator* m_pMediator;
};

#endif

 

colleague.cpp如下:

#include "mediator.h"
#include "colleague.h"

Calender::Calender( Mediator* pMediator )
{
	m_pMediator = pMediator;
}

void Calender::addEvent( int timeInSeconds, string desc )
{
	m_mapCalender[timeInSeconds] = desc;
	cout << "An event is added to calender: " << desc << " at " << timeInSeconds << endl;

	m_pMediator->addEventToCalender(timeInSeconds);
}

bool Calender::checkEvent( int timeInSeconds )
{
	map<int, string>::const_iterator iter = m_mapCalender.find(timeInSeconds);
	if (iter != m_mapCalender.end())
	{
		string desc = iter->second;
		cout << desc << " is due!" << endl;

		return true;
	}

	return false;
}

Alarm::Alarm( Mediator* pMediator )
{
	m_pMediator = pMediator;
}

void Alarm::setTimer( int timeInseconds )
{
	cout << "Alarm is set at " << timeInseconds << endl;
	times.push_back(timeInseconds);
}

void Alarm::start()
{
	cout << "Alarm starts at " << m_nTime << endl;
	m_pMediator->startAlarm(m_nTime);
}

void Alarm::stop()
{
	cout << "Alarm stops" << endl;
	m_pMediator->stopAlarm();
}

bool Alarm::isThereAlarm( int tm )
{
	vector<int>::const_iterator iter = times.begin();
	for (; iter != times.end(); ++iter)
		if (*iter == tm)
			return true;
	return false;
}

void Alarm::setTime( int nTime )
{
	m_nTime = nTime;
}

int Alarm::getTime()
{
	return m_nTime;
}

CoffeePot::CoffeePot( Mediator* pMediator, int nStart /*= 100000*/ )
{
	m_pMediator = pMediator;
	m_nStart = nStart;
}

void CoffeePot::cook(int nStart)
{
	cout << "Start cooking coffee at " << nStart << endl;
	m_nStart = nStart;
}

void CoffeePot::ready( int tm )
{
	cout << "Coffee is ready at " << tm << endl;
	m_pMediator->coffeeIsReady();
}

bool CoffeePot::isReady( int tm )
{
	if (tm - m_nStart >= 20)	//it takes 20 secs to make coffee
	{
		m_nStart = 100000;
		return true;
	}

	return false;
}

 

mediator.h如下:

#ifndef __MEDIATOR_H__
#define __MEDIATOR_H__

class Alarm;
class Calender;
class CoffeePot;

class Mediator
{
public:
	Mediator() {}

	void setAlarm(Alarm* pAlarm);
	void setCalender(Calender* pCalender);
	void setCoffeePot(CoffeePot* pCoffeepot);

	void startAlarm(int timeInSeconds);

	void stopAlarm();

	void addEventToCalender(int timeInSeconds);

	void coffeeIsReady();

private:
	Alarm* m_pAlarm;
	Calender* m_pCalender;
	CoffeePot* m_pCoffeePot;
};


#endif

 

mediator.cpp如下:

#include "colleague.h"
#include "mediator.h"

void Mediator::startAlarm( int timeInSeconds )
{
	m_pCalender->checkEvent(timeInSeconds);
}

void Mediator::stopAlarm()
{
	m_pCoffeePot->cook(m_pAlarm->getTime());
}

void Mediator::coffeeIsReady()
{
	m_pAlarm->start();
}

void Mediator::addEventToCalender( int timeInSeconds )
{
	m_pAlarm->setTimer(timeInSeconds);
}

void Mediator::setAlarm( Alarm* pAlarm )
{
	m_pAlarm = pAlarm;
}

void Mediator::setCalender( Calender* pCalender )
{
	m_pCalender = pCalender;
}

void Mediator::setCoffeePot( CoffeePot* pCoffeepot )
{
	m_pCoffeePot = pCoffeepot;
}

 

测试代码main.cpp如下:

#include "colleague.h"
#include "mediator.h"

int main()
{
	Mediator mediator;
	Alarm alarm(&mediator);
	Calender calender(&mediator);
	CoffeePot coffeePot(&mediator);

	mediator.setAlarm(&alarm);
	mediator.setCalender(&calender);
	mediator.setCoffeePot(&coffeePot);

	calender.addEvent(30, "get up");

	for (int tm = 0; tm < 1000; ++tm)
	{
		alarm.setTime(tm);

		if (alarm.isThereAlarm(tm))
		{
			alarm.start();
			alarm.stop();
		}
		if (coffeePot.isReady(tm))
			coffeePot.ready(tm);
	}

	return 0;
}

 

 

最终运行结果如下:

image

posted on 2011-12-08 22:18  GraphicsMe  阅读(396)  评论(0编辑  收藏  举报

导航