最近在复习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*);
};
#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;
}
代码不复杂,仅有的注释应该够了,
简单来说就是实作中间人、实作灯泡,
然后让灯泡认识中间人,中间人注册所有灯泡,
然后灯泡就可以开始交互了。
本来想全包成一个文件,后来觉得分门别类概念会比较清楚,就这样做了。