(七)中介者模式-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 ...
随机推荐
- Method Draw – 很好用的 SVG 在线编辑器
Method Draw 是一款在线 SVG 编辑器,是 SVG Edit 的一个分支.Method Draw 的目的是改进 SVG Edit 的可用性和用户体验.它移除了 line-caps/corn ...
- atom编辑markdown之上传图片
01atom编辑markdown之上传图片 :first-child { margin-top: 0px; } .markdown-preview:not([data-use-github-style ...
- sizzle源码分析 (2)ID 类 tag querySelectorAll 快速匹配
不是所有的选择器都需要去分词,生成相应的匹配函数,这样流程比较复杂,当浏览器具备原生的方法去匹配元素是,没有理由不优先匹配,下面看看进入Sizzle后,它是怎么优先匹配这些元素的: function ...
- ArcCatalog中连接SDE数据库
描述 在ArcCatalog采用直接的方式连接SDE数据库时,无论怎样填写连接参数,都连接不上(数据库管理工具和代码都可以连).主要报两类错误: Error:ORA-12154:TNS:无法解析指定的 ...
- sharepoint项目遇到的WebDAV和HTTP PUT的安全隐患解决办法
最近一个项目,客户进行了安全检测,检测出如下安全隐患,其实这些隐患全是IIS设置的事情 许多人误认为SharePoint是在使用由IIS提供的WebDAV功能. 实际上, SharePoint在S ...
- SharePoint 2013 JavaScript API 记录
1.获取创建者字段(Author),oListItem为SPListItem对象 oListItem.get_item('Author')只能获取到对象,获取用户名要用oListItem.get_it ...
- iOS-字符属性NSAttributedString描述
/* 字符属性 字符属性可以应用于 attributed string 的文本中. NSString *const NSFontAttributeName;(字体) NSString *const N ...
- github邮箱验证技巧
申请的github账号,绑定邮箱之后才能创建库,而反复几次的发送邮件均为收到验证邮件,猜测有两个原因: 1.腾讯邮件服务器屏蔽了github的来信 (腾讯不会这么狭隘的,×) 2.自己邮箱的域名黑名单 ...
- yii2中自定义验证规则rules
作者:白狼 出处:www.manks.top/article/yii2_custom_rules 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追 ...
- 配置mysql远程访问权限,大家可能掉过的那些坑~
1 作为互联网技术从业人 或者粗暴点说:作为一个程序猿.测试从业者 如果没掉过一些坑,都不好意思说自己混过技术圈 2 今天重点讲:mysql开启远程访问权限的那些坑- 对于mysql开启远程访 ...