(七)中介者模式-C++实现
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使其解耦合松散而且可以独立地改变他们之间的交互。
中介者模式适合于 系统中不希望对象之间直接交互,即不希望类之间相互包含,成为朋友。
中介者模式中有四种角色:
(1)中介者:定义了用于同事之间通信的方法
(2)具体中介者:如果只有一个中介者,那么可以只有一个具体中介者,不需要抽象中介者。它包含具体同事的引用,实现他们之间的通信。
(3)同事:抽象类,规定一些方法
(4)具体同事:包含具体中介者的引用,一个具体同事需要和其他同事交互时,将自己的请求通知给他包含的具体中介者即可。
在本例子中,同事A分别需要通知B和C一些消息,而B也需要通知A和C一些消息,同样,C也需要通知A和B一些消息。利用中介者模式实现如下:
(1)Colleague.h
#ifndef _COLLEAGUE_H_
#define _COLLEAGUE_H_
#include <string>
#include <iostream>
#include "Mediator.h"
using namespace std;
class ConcreteMediator; //中介者模式
//抽象同事和具体同事的定义 如果没有中介者 他们需要相互包含
class Colleague{
public:
virtual void giveMess(string mess[]) = ;
virtual void receiverMess(string mess) = ;
virtual void setName(string name) = ;
virtual string getName() = ; }; //具体同事
class ColleagueA : public Colleague{
public:
ColleagueA(ConcreteMediator *mediator);
void setName(string name) override;
string getName() override;
void giveMess(string mess[]) override;
void receiverMess(string name) override; private:
ConcreteMediator *myMediator;
string name; }; class ColleagueB : public Colleague{
public:
ColleagueB(ConcreteMediator *mediator);
void setName(string name) override;
string getName() override;
void giveMess(string mess[]) override;
void receiverMess(string name) override; private:
ConcreteMediator *myMediator;
string name; }; class ColleagueC : public Colleague{
public:
ColleagueC(ConcreteMediator *mediator);
void setName(string name) override;
string getName() override;
void giveMess(string mess[]) override;
void receiverMess(string name) override; private:
ConcreteMediator *myMediator;
string name; }; #endif
(2)Colleague.cpp
#include "Colleague.h" ColleagueA::ColleagueA(ConcreteMediator *mediator)
{
this->myMediator = mediator;
myMediator->registerColleagueA(this);
} void ColleagueA::setName(string name)
{
this->name = name;
} string ColleagueA::getName()
{
return name;
} void ColleagueA::giveMess(string mess[])
{
//由中介者将消息传递给其同事
myMediator->deliverMess(this, mess);
} void ColleagueA::receiverMess(string mess)
{
cout << name << " get message: " << mess << endl;
} ColleagueB::ColleagueB(ConcreteMediator *mediator)
{
this->myMediator = mediator;
myMediator->registerColleagueB(this);
} void ColleagueB::setName(string name)
{
this->name = name;
} string ColleagueB::getName()
{
return name;
} void ColleagueB::giveMess(string mess[])
{
//由中介者将消息传递给其同事
myMediator->deliverMess(this, mess);
} void ColleagueB::receiverMess(string mess)
{
cout << name << " get message: " << mess << endl;
} ColleagueC::ColleagueC(ConcreteMediator *mediator)
{
this->myMediator = mediator;
myMediator->registerColleagueC(this);
} void ColleagueC::setName(string name)
{
this->name = name;
} string ColleagueC::getName()
{
return name;
} void ColleagueC::giveMess(string mess[])
{
//由中介者将消息传递给其同事
myMediator->deliverMess(this, mess);
} void ColleagueC::receiverMess(string mess)
{
cout << name << " get message: " << mess << endl;
}
(3)Mediator.h
#ifndef _MEDIATOR_H_
#define _MEDIATOR_H_
#include "Colleague.h"
#include <string>
using namespace std; class Colleague;
class ColleagueA;
class ColleagueB;
class ColleagueC; //中介者 由于本例子中只有一个中介者 所以只定义一个具体中介者 class ConcreteMediator{
public:
void registerColleagueA(ColleagueA *ca);
void registerColleagueB(ColleagueB *cb);
void registerColleagueC(ColleagueC *cc); void deliverMess(Colleague *colleague, string mess[]); private:
ColleagueA *ca;
ColleagueB *cb;
ColleagueC *cc;
}; #endif
(4)Mediator.cpp
#include "Mediator.h" void ConcreteMediator::registerColleagueA(ColleagueA *ca)
{
this->ca = ca;
} void ConcreteMediator::registerColleagueB(ColleagueB *cb)
{
this->cb = cb;
} void ConcreteMediator::registerColleagueC(ColleagueC *cc)
{
this->cc = cc;
} void ConcreteMediator::deliverMess(Colleague *colleague, string mess[])//如果这里需要判断mess的长度,需要将其作为参数传递进来
{
if (typeid(*colleague) == typeid(*ca))
{
//通知其他的同事
cb->receiverMess(colleague->getName() + mess[]);
cc->receiverMess(colleague->getName() + mess[]);
}
else if (typeid(*colleague) == typeid(*cb))
{
ca->receiverMess(colleague->getName() + mess[]);
cc->receiverMess(colleague->getName() + mess[]);
}
else if (typeid(*colleague) == typeid(*cc))
{
ca->receiverMess(colleague->getName() + mess[]);
cb->receiverMess(colleague->getName() + mess[]);
}
}
(5)MediatorMain.cpp
#include "Colleague.h"
#include "Mediator.h" int main()
{
ConcreteMediator *mediator = new ConcreteMediator(); ColleagueA *ca = new ColleagueA(mediator);
ColleagueB *cb = new ColleagueB(mediator);
ColleagueC *cc = new ColleagueC(mediator); ca->setName("国A");
cb->setName("国B");
cc->setName("国C"); string messA[] = { "要求归还100斤土豆", "要求归还20头牛" };
ca->giveMess(messA);
cout << endl;
string messB[] = { "要求归还10只鸡", "要求归还15匹马" };
cb->giveMess(messB);
cout << endl;
string messC[] = { "要求归还300斤小麦", "要求归还50头驴" };
cc->giveMess(messC); return ;
}
需要注意的是,在中介者中传递消息的时候需要判断当前参数中指向的对象是哪种类型,用到了操作符typeid。它的参数类型是对象,若两个对象是同一个类型则返回true。
中介者模式适合于一个对象需要引用很多其他对象,或者是对象之间的相互引用比较多的情况。
优点也有很多,比如:
(1)将分布于多个对象之间的交互行为集中在一起。
(2)使得各个具体同事之间完全解耦。
等。
(七)中介者模式-C++实现的更多相关文章
- 23种设计模式--中介者模式-Mediator Pattern
一.中介者模式的介绍 中介者模式第一下想到的就是中介,房子中介,婚姻中介啊等等,当然笔者也希望来个婚姻中介给我介绍一个哈哈哈,,回归正题中介者模式分成中介者类和用户类,根据接口编程的方式我们再 ...
- 设计模式--中介(Mediator)模式
时隔很长一段时,现在又重温设计模式,上个星期学习<设计模式--代理(Proxy)模式>http://www.cnblogs.com/insus/p/4128814.html. 温故而知新, ...
- 设计模式---接口隔离模式之中介者模式(Mediator)
一:概念 在Mediator模式中,类之间的交互行为被统一放在Mediator的对象中,对象通过Mediator对象同其他对象交互.Mediator对象起到控制器的作用 二:动机 在软件构建的过程中, ...
- 行为型模式(五) 中介者模式(Mediator)
一.动机(Motivate) 为什么要使用中介者模式呢?如果不使用中介者模式的话,各个同事对象将会相互进行引用,如果每个对象都与多个对象进行交互时,将会形成如下图所示的网状结构.从上图可以发现,如果不 ...
- MediatorPattern(中介者模式)
/** * 中介者模式 * @author TMAC-J * 研究了这么多设计模式,觉得无非就是几点: * 1.若两个类有耦合关系,设立一个中间类,处理两个类的关系,把两个类的耦合降低 * 2.面向接 ...
- C#设计模式-中介者模式
在现实生活中,有很多中介者模式的身影,例如QQ游戏平台,聊天室.QQ群和短信平台,这些都是中介者模式在现实生活中的应用,下面就具体分享下我对中介者模式的理解. 一. 中介者(Mediator)模式 从 ...
- php实现设计模式之 中介者模式
<?php /* * 中介者模式:用一个中介对象来封装一系列的对象交互,使各对象不需要显式地相互引用从而使其耦合松散,而且可以独立地改变它们之间的交互 */ /* * 以一个同学qq群为例说明, ...
- 轻松掌握:JavaScript代理模式、中介者模式
代理模式.中介者模式 代理模式 在面向对象设计中,有一个单一职责原则,指就一个类(对象.函数)而言,应该仅有一个引起它变化的原因.如果一个对象承担了过多的职责,就意味着它将变得巨大,引起它变化的原因就 ...
- java设计模式之中介者模式
中介者模式 用一个中介对象来封装一系列的对象交互.中介者使各个对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 中介者模式UML图 中介者模式代码 package com ...
随机推荐
- angular源码分析:angular中jqLite的实现——你可以丢掉jQuery了
一.从function JQLite(element)函数开始. function JQLite(element) { if (element instanceof JQLite) { //情况1 r ...
- Navigator对象、Screen对象
Navigator对象: Window对象的navigator属性引用的是包含浏览器厂商和版本信息的Navigator对象: Navigator对象集合:plugins[] 返回对 ...
- CSS3动画(个人理解)
随着学习的深入,越来越觉得Css3动画的重要,虽然JQ自定义动画和动画回调函数必须掌握,但是css3动画做起来更加绚丽,更加方便!1.常规使用1.1 使用transition属性,一般我们是配合hov ...
- 内网渗透测试思路-FREEBUF
(在拿到webshell的时候,想办法获取系统信息拿到系统权限) 一.通过常规web渗透,已经拿到webshell.那么接下来作重要的就是探测系统信息,提权,针对windows想办法开启远程桌面连接, ...
- android listview多视图嵌套多视图
笔记,listview视图总结 public class HomeEduMoreAdapter extends BaseAdapter { private final String TAG = &qu ...
- gif动图快速制作方法(附工具)
现在写博客或是wiki的过程中,会经常引用到图片,特别是客户端经常与页面相关所以截图不可避.但是越来越多的效果仅仅一张图片是无法清楚的描述.并且博客或是wiki也是支持gif图的.gif图的制作方法有 ...
- [转]setValue和setObject的区别
在使用NSMutableDictionary的时候经常会使用setValue forKey与setObject forKey,他们经常是可以交互使用的,代码中经常每一种的使用都有. 1,先看看setV ...
- 学习 HTML5-目录
1.学习 HTML5-页面结构 2.HTML5标记 3.HTML5机构化语义元素 4.HTML5表单 5.HTML5媒体元素:Audio和Video 6.HTML5绘图API 7.HTML5 Canv ...
- IntelliJ IDEA 导入新项目以后的简单配置
首先,配置Maven. 然后,配置Git. 选择自己调试要用的默认浏览器. 进行Edit Configurations 配置: 转载请注明出处! http://www.cnblogs.com/libi ...
- Android四大组件之Activity & Fragement
1.Activity的生命周期