中介者模式的应用之用电脑播放电影

思考中介者模式

(1)中介者模式的本质封装交互。中介者的目的,就是用来封装多个对象的交互,这些交互的处理多在中介者对象里面实现。只要是实现封装对象之间的交互功能,就可用中介者模式,而不必过于拘泥于中介者模式本身的结构。

(2)需要Mediator接口吗

  这取决于是否会提供多个不同的中介者实现。如果中介者实现只有一个的话,而且预计中也没有扩展的需求,那就可以不定义Mediator接口。如果中介者实现不只一个,或者预计有扩展的要求,那么就需要定义Mediator接口。让各个同事类来面向中介者接口编程。

(3)同事关系

  在标准的中介者模式中,将使用中介者对象来交互的那些对象称为同事类,在中介者模式中要求这些类都要继承相同的类,也就是说这些对象从某个角度来讲是同一个类型,算是兄弟对象。

(4)同事和中介者的关系

  ①当一个同事对象发生了改变,需要主动通知中介者,让中介者去处理与其他同事对象相关的交互。

  ②同事对象需要知道中介者对象是谁,反过来,中介者对象也需要知道相关的同事对象,这样才能与同事对象进行交互。

  ③中介者对象与同事对象之间是相互依赖的。

(5)如何实现同事和中介者的通信

  ①同事类持有中介者对象,可以通过Mediator接口中定义一个特殊的通知接口(如changed),并把this当做参数传入,这样在中介者对象里面,就可以去获取这个同事对象的实例或当中的数据了。中介者对象里面记录着各个同事,会根据从changed接口中传入来的对象,判断下一步的动作。

  ②另一种实现方式可以采用观察者模式,把Mediator实现成为观察者,而各个同事类实现成为Subject,这样同事类发生了改变,会通知Mediator。Mediator在接到通知的以后,会与相应的同事对象进行交互。

【编程实验】用电脑看电影


//行为模式——中介者模式
//场景:使用电脑来看电影
//中介者:主板
//同事类:CPU、内存、光驱、显卡、声卡等

#include <iostream>
#include <string>
#include <vector>

using namespace std;

class CHardware;//前向声明

//*******************************************抽象中介者**************************************
//抽象中介者
class CAbsMediator{
public:
	//同事对象在自身改变的时候调用这个接口来通知中介者
	virtual void Changed(CHardware* hardware) = 0;
};
//*******************************************抽象同事类**************************************
//抽象同事类
class CHardware{
protected:
	CAbsMediator* pMediator;
public:
	CHardware(CAbsMediator* mediator){pMediator = mediator;}
	//获取当前同事类对应的中介者对象
	CAbsMediator& GetMediator(){return *pMediator;}
};

//具体的同事类:光驱
class CCdDrv : public CHardware{
private:
	string strDat;
public:
	CCdDrv(CAbsMediator* mediator) : CHardware(mediator){}
	void ReadCd(){//读取光盘
		//逗号前是视频显示的数据,逗号后是声音
		strDat = "设计模式,值得好好研究";
		//通知中介者(主板),自己的状态发生了改变
		pMediator->Changed(this);
	}
	string& GetDat(){return strDat;}
};


//具体的同事类:CPU
class CCpu : public CHardware{
private:
	string strVideo;//分解出来的视频数据
	string strSound;//分解出来的声音数据
public:
	CCpu(CAbsMediator* mediator) : CHardware(mediator){}
	string& GetVideo(){return strVideo;}
	string& GetSound(){return strSound;}
	void DispartData(string data){//处理数据,把数据分成音频和视频数据
		int iPos = data.find(",");
		strVideo = data.substr(0, iPos);
		strSound = data.substr(iPos+1, data.length()-iPos);
		//通知主板,CPU的工作完成
		pMediator->Changed(this);
	}
};

//具体的同事类:显卡类
class CVideoCard : public CHardware{
private:
	string strVideo;//被显示的数据
public:
	CVideoCard(CAbsMediator* mediator) : CHardware(mediator){}
	void DispVideo(string data){
		cout << "您正在观看的是:" << data << endl;
	}
};

//具体的同事类:声卡类
class CSoundCard : public CHardware{
private:
	string strSound;//被播放的声音数据
public:
	CSoundCard(CAbsMediator* mediator) : CHardware(mediator){}
	void DispSound(string data){//显示数据
		cout << "画外音:" << data << endl;
	}
};

//*************************************具体中介者****************
//主板类
class CMainBoard : CAbsMediator{
private:
	CCdDrv* pCdDrv;
	CCpu* pCpu;
	CVideoCard* pVc;
	CSoundCard* pSc;
public:
	CMainBoard()
	{
		pCdDrv = new CCdDrv(this);
		pCpu = new CCpu(this);
		pVc = new CVideoCard(this);
		pSc = new CSoundCard(this);
	}
	~CMainBoard()
	{
		delete pCdDrv; pCdDrv = NULL;
		delete pCpu; pCpu = NULL;
		delete pVc; pVc = NULL;
		delete pSc; pSc = NULL;
	}
	CCdDrv* GetCd(){return pCdDrv;}
	//处理光驱读取数据以后与其他对象的交互
	void CdDrvReadDat(CCdDrv* cd){
		//1.获取光驱读取的数据
		string strData = cd->GetDat();
		//2.把这些数据传给CPU进行处理
		pCpu->DispartData(strData);
	}
	//CPU处理完数据后与其他对象的交互
	void CpuParseDat(CCpu* cpu){
		//1.先取出CPU处理后的数据
		string strVideo = cpu->GetVideo();
		string strSound = cpu->GetSound();
		//2. 把数据传递给显卡和声卡展示出来
		pVc->DispVideo(strVideo);
		pSc->DispSound(strSound);
	}
	//接收通知
	void Changed(CHardware* hardware){
		if(hardware == pCdDrv)				CdDrvReadDat(pCdDrv);
		else if(hardware == pCpu)			CpuParseDat(pCpu);
	}
};


void WatchFilm()
{
	CMainBoard oMainBoard;
	//开始看电影,把光盘放入光驱,光驱开始读盘
	oMainBoard.GetCd()->ReadCd();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值