设计模式系列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来完成,关系图如下:
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; }
最终运行结果如下:
posted on 2011-12-08 22:18 GraphicsMe 阅读(396) 评论(0) 编辑 收藏 举报