[C++] Mediator Pattern 实作

最近在复习Design Pattern,好久没用都有些忘记了,主要是没什么机会做开发实践。



Mediator 实现了一个中间人处理机制,适合应用的情境是:

1) 当多个实体(或物件)互相交互时,相互间的关系多样且复杂,

2) 或者一个实体同时与多个实体交互时。想通过一种方式减少交互量。


就像视频衣果聊,美眉同时和多个观众互动,若是对每个人都用不同的视频软件(QQ、SKYPE、WEB),那肯定很麻烦,

观众之间要交流也不容易,

所以,如果大家能在同一个平台上面互动那多好。


中间人的设计模式结构长下面这样:


Mediator抽象类  就是中间人,就是大家互相交互的接口。

ConcreteMediator类  就是Mediator的实作,此中间人实体需要认识所有互相交互的Colleage类实体,以达成互相交互。

Colleage抽象类  是所有欲交互实体的父类别。

ConcreteColleage类  是Colleage的实作,每一个实体都要认识中间人,但是实体之间不需互相认识,只需定义自己的行为。


下面实作了中间人模式的具体代码,

代码功能主要是模拟三个电灯泡,当用户手摸其中一个时,另外两个灯泡同时切换开关。

Use case:

A、B、C三灯泡,初始全暗

(1) 手摸B,则A、C转亮

(2) 手再摸A,则B转亮、C转暗

最后结果就是  A亮、B亮、C暗

反正就是手摸其中一个,另外两个改变状态。


当然,改变状态的指令可以想像为由手摸到的灯泡呼叫中间人,让中间人去执行摸到灯泡后对应的动作,

功能实作都包在中间人类里,其他人都不会知道。

//


上代码!

[CBulb.h]  这个就是Colleage抽象类,之后要实作他成为灯泡实体

#ifndef _CBULB_
#define _CBULB_

#include "CMediator.h"

class CMediator;

class CBulb {
public:
	CBulb();
	CBulb(char *, bool, CMediator*);
	~CBulb();
	void ShowStatus();
	void ChangeStatus();
	void Off();
	void Press();
	CMediator *med;
	char *name;
	bool status; // bulb lighting or not: {0, 1}
};
#endif



[ CBulbA.h] 灯泡A类,继承了Colleage

#ifndef _CBULBA_
#define _CBULBA_

#include "CBulb.h"

class CBulbA : public CBulb {
public:
	CBulbA();
	CBulbA(char *, bool, CMediator*);
	~CBulbA();
};
#endif

B和C灯泡与A相同就不摆上来了。


[CBulb.cpp] Colleage类的内容,说是抽象类其实一点也不抽象啊,我是不是不该这么写啊

#include "CBulb.h"

CBulb::CBulb()
{
}

CBulb::CBulb(char *str, bool status, CMediator* med)
{
	this->status=status;
	name=strdup(str);
	this->med=med;
}

CBulb::~CBulb()
{
}

void CBulb::ShowStatus()
{
	printf("Bulb %s:%s\n", name, status?"true":"false");
}

void CBulb::ChangeStatus()
{
	status=!status;
}

void CBulb::Off()
{
	status=false;
}

void CBulb::Press()
{
	med->ChangeStatus(name);
}


[CBulbA.cpp] 灯泡A类实体

#include <string.h>
#include "CBulbA.h"

CBulbA::CBulbA()
{
	
}

CBulbA::CBulbA(char *str, bool status, CMediator* med)
{
	this->status=status;
	name=strdup(str);
	this->med=med;
}

CBulbA::~CBulbA()
{
}


[Mediator.h] 中间人抽象类

#ifndef _CMEDIATOR_
#define _CMEDIATOR_

#include "CBulb.h"
#include <vector>
using namespace std;

class CBulb;

class CMediator {
public:
	CMediator();
	~CMediator();
	virtual void RegistBulb(CBulb*);
	virtual void ChangeStatus(char*);
	vector<CBulb*> rulbList;
};
#endif

[ ConcreteMediator.h] 中间人类实作

#include "CMediator.h"

class CConcreteMediator : public CMediator {
public:
	CConcreteMediator();
	~CConcreteMediator();
	void RegistBulb(CBulb*);
	void ChangeStatus(char*);
};



[ Mediator.cpp] 中间人抽象类内容

#include "CMediator.h"

CMediator::CMediator()
{
}

CMediator::~CMediator()
{
}

void CMediator::RegistBulb(CBulb *bulb)
{
}

void CMediator::ChangeStatus(char* name)
{
}


[ ConcreteMediator.cpp] 中间人类实作内容,充当接口的类,所有Colleage交互的功能都写在这里面

#include "CConcreteMediator.h"

CConcreteMediator::CConcreteMediator()
{
}

CConcreteMediator::~CConcreteMediator()
{
}

void CConcreteMediator::RegistBulb(CBulb *bulb)
{
	rulbList.push_back(bulb);
}

void CConcreteMediator::ChangeStatus(char *name)
{
	int i=0;
	if(strcmp(name, "A")==0) // B & C light change
	{
		for(i=0;i<rulbList.size();i++)
		{
			if(strcmp(rulbList[i]->name, "B")==0)
			{
				rulbList[i]->ChangeStatus();
			}
			else if(strcmp(rulbList[i]->name, "C")==0)
			{
				rulbList[i]->ChangeStatus();
			}
		}
	}
	else if(strcmp(name, "B")==0) // A & C light change
	{
		for(i=0;i<rulbList.size();i++)
		{
			if(strcmp(rulbList[i]->name, "A")==0)
			{
				rulbList[i]->ChangeStatus();
			}
			else if(strcmp(rulbList[i]->name, "C")==0)
			{
				rulbList[i]->ChangeStatus();
			}
		}
	}
	else if(strcmp(name, "C")==0) // A & B light change
	{
		for(i=0;i<rulbList.size();i++)
		{
			if(strcmp(rulbList[i]->name, "A")==0)
			{
				rulbList[i]->ChangeStatus();
			}
			else if(strcmp(rulbList[i]->name, "B")==0)
			{
				rulbList[i]->ChangeStatus();
			}
		}
	}
	else if(strcmp(name, "1")==0) // All light off
	{
		for(i=0;i<rulbList.size();i++)
		{
			rulbList[i]->Off();
		}
	}
}


[Main.cpp] 主程序

/*
 *This program use the "Mediator Pattern" simulating light-changes for a set of multiple bulbs.
 *Author: Jordan Yeh
 *Date: 2015/04/23
 */

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include "CBulbA.h"
#include "CBulbB.h"
#include "CBulbC.h"
#include "CConcreteMediator.h"

void main()
{
	char input;
	// declare mediator
	CConcreteMediator med; 
	// let all colleage know the mediator
	CBulbA bulb_a=CBulbA("A", false, &med); 
	CBulbB bulb_b=CBulbB("B", false, &med);
	CBulbC bulb_c=CBulbC("C", false, &med);
	// let mediator know all colleage
	med.RegistBulb(&bulb_a);
	med.RegistBulb(&bulb_b);
	med.RegistBulb(&bulb_c);

	while(1)
	{
		system("cls");
		bulb_a.ShowStatus();
		bulb_b.ShowStatus();
		bulb_c.ShowStatus();
		printf("==Select one bult to press==\n");
		printf("  (A) B & C light change\n");
		printf("  (B) A & C light change\n");
		printf("  (C) A & B light change\n");
		printf("  (1) All light off\n");
		printf("  (2) Exit programe\n");
		input=getch();
		switch(input)
		{
			case '1':
				med.ChangeStatus("1");
				break;
			case '2':
				return;
				break;
			case 'A':
			case 'a':
				bulb_a.Press();
				break;
			case 'B':
			case 'b':
				bulb_b.Press();
				break;
			case 'C':
			case 'c':
				bulb_c.Press();
				break;
			default:
				continue;
		}
	}
	return;
}


代码不复杂,仅有的注释应该够了,

简单来说就是实作中间人、实作灯泡,

然后让灯泡认识中间人,中间人注册所有灯泡,

然后灯泡就可以开始交互了。


本来想全包成一个文件,后来觉得分门别类概念会比较清楚,就这样做了。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值