设计模式之中介者模式(Mediator)

一、初识中介者模式

那些年,我们一起上过的大学,班级里有班长,有团书记。想一想如果没有QQ这种通讯工具的话,那么班长或者团支书该怎样下达消息呢??同时,班级上两个同学之间也可惜沟通啊,沟通一下,院里哪个女生,哪个帅哥呀~~~如果没有QQ的话,大概就是下面的情景:

哎呀呀,看看这个乱那。如果同学的数目多起来就会变成网状的结构啦。原本把一个系统分割成一些对象是可以增强复用性的,但是现在的情况是,这些兑现之间存在着大量的联系,耦合性极高。这是很不利于复用的,同时这种情况使得系统的灵活性大大的降低,使得对系统的扩展很难,要是新转来一个学生的话,要改动的地方就多了去了。

如果现在可以使用QQ,那么可以采用另一种方式设计这个系统呢,比如做成星形的结构:

看看这种“星形结构”和“网状结构”的区别吧,显然采用星形结构就可以避免上面的网状结构存在的问题了,实际上这里的QQ就是指的是中介,这样一来每个学生对象就不用存在耦合了,同学之间需要交流可以通过一个QQ群。

本人认为,由原来的网状结构到星形结构的转变是理解中介者模式比较好的途径,下面来具体看看中介者模式,GoF说:


中介者模式(Mediator Pattern):定义一个中介对象来封装系列对象之间的交互。中介者使各个对象不需要显示地相互引用,从而使其耦合性松散,而且可以独立地改变他们之间的交互。


看看结构图的形象描述吧:

对于设计模式这个东西,理解了,应该写一个代码体会一下:看看这些类,比如:Mediator,ConcreteMediator,Colleague和ConcreteColleage1到底是怎么组织的。

 #include <iostream>
#include <vector>
#include <string> using namespace std; //抽象的同事类
class Colleage
{
private:
string name;
string content;
public:
Colleage(string n = " "):name(n){};
void set_name(string name)
{
this->name = name;
}
string get_name()
{
return this->name;
}
void set_content(string content)
{
this->content = content;
}
string get_content()
{
return content;
}
virtual void talk(){}; };
//具体的同事类:班长
class Monitor : public Colleage
{
public:
Monitor(string n = ""):Colleage(n){};
virtual void talk()
{
cout<<"大班长 说:"<<get_content()<<endl;
}
};
//具体的同事类:团支书
class TuanZhiShu : public Colleage
{
public:
TuanZhiShu(string n = ""):Colleage(n){};
virtual void talk()
{
cout<<"团支书 说:"<<get_content()<<endl;
}
};
//具体的同事类:同学A
class StudentA : public Colleage
{
public:
StudentA(string n = ""):Colleage(n){};
virtual void talk()
{
cout<<"学生 A 说:"<<get_content()<<endl;
}
};
//具体的同事类:同学B
class StudentB : public Colleage
{
public:
StudentB(string n = ""):Colleage(n){};
virtual void talk()
{
cout<<"学生 B 说:"<<get_content()<<endl;
}
};
//抽象中介者
class Mediator
{
public:
vector<Colleage*> studentList;
virtual void add_student(Colleage *student)
{
studentList.push_back(student);
};
virtual void notify(Colleage *student){};
virtual void chart(Colleage *student1,Colleage *student2){};
};
//具体中介者qq通讯平台
class QQMediator : public Mediator
{
public:
virtual void notify(Colleage *student)
{
student->talk();
for(int i = ; i < studentList.size() ; ++i)
{
//不是说话者
if(student != studentList[i])
{
studentList[i]->talk();
}
}
};
virtual void chart(Colleage *student1,Colleage *student2)
{
student1->talk();
student2->talk();
}
}; int main()
{
QQMediator qq;
Monitor studentMonitor("Vincent");
TuanZhiShu studentTuanZhiShu("Robort");
StudentA studentA("Sam");
StudentB studentB("Tom");
/*----------------------班长发通知-----------------------------*/
cout<<"下面的班长发布一个通知的场景:"<<endl;
//将同学们加入到qq群中
qq.add_student(&studentMonitor);
qq.add_student(&studentTuanZhiShu);
qq.add_student(&studentA);
qq.add_student(&studentB);
//设置大家的回复信息
studentMonitor.set_content("明天下午2点开年级会,收到回复^^。");
studentTuanZhiShu.set_content("知道了,肯定到!!");
studentA.set_content("收到了,但是可能晚点到!!");
studentB.set_content("收到了,但是明天要去面试!!");
//开始发通知
qq.notify(&studentMonitor);
/*--------------------两个同学私下交流--------------------------*/
cout<<endl<<"下面是两个同学的私下交流:"<<endl;
studentMonitor.set_content("你觉得咱们“软件项目管理老师”讲的怎么样?");
studentA.set_content("我觉得讲的不够生动,还点名,不太好!!!");
qq.chart(&studentMonitor,&studentA);
return ;
}

下面是运行的结果:

看看,这样就利用qq这个平台完成了同学之间的交流。并且同学之间并没有相互联系,联系都是通过qq实现的,如果现在要对象进行扩展,比如也可以通过飞信啊,只需要加入class FeiXin:public Mediator 就可以了,如果想扩展同学C只需要,class StudentC:public Colleage 即可。并且在客户端的使用也是很方便的哦~~这时回过头想一想如果不用“中介者模式”的话,系统会是什么样呢???

二、使用中介者模式的场合和优缺点

使用终结者模式的场合

1.一组定义良好的对象,现在要进行复杂的通信。

2.定制一个分布在多个类中的行为,而又不想生成太多的子类。

可以看出,中介对象主要是用来封装行为的,行为的参与者就是那些对象,但是通过中介者,这些对象不用相互知道。呵呵~~~

使用中介者模式的优点:

1.降低了系统对象之间的耦合性,使得对象易于独立的被复用。

2.提高系统的灵活性,使得系统易于扩展和维护。

使用中介者模式的缺点:

中介者模式的缺点是显而易见的,因为这个“中介“承担了较多的责任,所以一旦这个中介对象出现了问题,那么整个系统就会受到重大的影响。


学习中的一点总结,欢迎拍砖哦^^


 
 
posted on 2012-08-30 17:23 VincentCZW 阅读(6043) 评论(6) 编辑 收藏
 
Comments
 
 
Powered by:
博客园
Copyright © VincentCZW

中介者模式(QQ聊天室我觉得是个很生动的例子简单易懂)的更多相关文章

  1. c++实现中介者模式--虚拟聊天室

    内容: 在"虚拟聊天室"实例中增加一个新的具体聊天室类和一个新的具体会员类,要求如下: 1. 新的具体聊天室中发送的图片大小不得超过20M. 2. 新的具体聊天室中发送的文字长度不 ...

  2. python模拟QQ聊天室(tcp加多线程)

    python模拟QQ聊天室(tcp加多线程) 服务器代码: from socket import * from threading import * s = socket(AF_INET,SOCK_S ...

  3. Netty 仿QQ聊天室 (实战二)

    Netty 聊天器(百万级流量实战二):仿QQ客户端 疯狂创客圈 Java 分布式聊天室[ 亿级流量]实战系列之15 [博客园 总入口 ] 源码IDEA工程获取链接:Java 聊天室 实战 源码 写在 ...

  4. 非阻塞模式ServerSocketChannel 聊天室服务器端

    import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import ja ...

  5. 设计模式之二十一:中介者模式(Mediator)

    中介者模式:定义了一个对象.用来封装一系列对象的交互.中介者模式通过使对象之间不必显式引用减少了对象之间的耦合,而且同意你独立改变它们之间的交互. 中介者模式就是将对象之间的交互封装在了一个独立的对象 ...

  6. javascript中的中介者模式——迪米特法则

    ”迪米特法则“——最少知识原则,不和陌生人说话,就是说,一个对象应当对其他对象有尽可能少的了解.talk only to your immediate friends.初衷是:降低对象之间的耦合度. ...

  7. PHP设计模式之中介者模式

    上回说道,我们在外打工的经常会和一类人有很深的接触,那就是房产中介.大学毕业后马上就能在喜欢的城市买到房子的X二代不在我们的考虑范围内哈.既然需要长期的租房,那么因为工作或者生活的变动,不可避免的一两 ...

  8. java bio 之聊天室

    最近在复习java io相关知识 ,发现很多细节之前没学习到位,原理也没吃透,只能感叹本人愚钝. 复习到bio,顺手写了个简单的聊天室功能,并和大家分享下. 服务端: package io.QQ聊天室 ...

  9. 基于Server-Sent Event的简单在线聊天室

    Web即时通信 所谓Web即时通信,就是说我们可以通过一种机制在网页上立即通知用户一件事情的发生,是不需要用户刷新网页的.Web即时通信的用途有很多,比如实时聊天,即时推送等.如当我们在登陆浏览知乎时 ...

随机推荐

  1. 浅谈Http、TCP、UDP和 IP 的的区别

    应用层:Http,超文本传输协议(HyperText Transfer Protocal):利用TCP在两台电脑(通常是Web服务器和客户端)之间传输信息的协议.客户端使用Web浏览器发起HTTP请求 ...

  2. 机器学习入门-贝叶斯中文新闻分类任务 1. .map(做标签数字替换) 2.CountVectorizer(词频向量映射) 3.TfidfVectorizer(TFDIF向量映射) 4.MultinomialNB()贝叶斯模型构建

    1.map做一个标签的数字替换 2.vec = CountVectorizer(lowercase=False, max_features=4000)  # 从sklean.extract_featu ...

  3. as3 三行三列 布满9个为一个界面

    var n:int=int(iconIndex/3); e.x =(int(n/3)*3+iconIndex%3)*557; e.y = int(iconIndex / 3) % 3 * 260; i ...

  4. UI5-文档-2.4-Node.js-Based开发环境

    用于修改OpenUI5.环境是基于Node.js,用作服务器,具有一个基于Grunt的构建过程.本节提供关于初始设置.开发工作流和测试执行的信息. 常规开发过程: 不需要构建过程,您可以简单地修改任何 ...

  5. where 命令

    在当前目录及path环境变量指定的目录中搜索相应文件 例:where msbuild 查找msbuild的位置

  6. ansible随记

    先来看一下ansible架构图: 一.官网的语法简单介绍 #选择的主机组 - hosts: webservers #这个是变量   vars:     http_port: 80     max_cl ...

  7. FileOperator 文件(夹)操作类

    public class FileOperator { /** * 复制文件目录 * @param srcDir 要复制的源目录 eg:/mnt/sdcard/DB * @param destDir ...

  8. Haskell语言学习笔记(31)ListT

    Control.Monad.Trans.List 标准库中的 ListT 的实现由于有 bug,已经被废弃. list-t 模块 这里使用 list-t 模块中的 ListT. list-t 模块需要 ...

  9. 协同过滤 spark scala

    1 http://www.cnblogs.com/charlesblc/p/6165201.html [转载]协同过滤 & Spark机器学习实战 2 基于Spark构建推荐引擎之一:基于物品 ...

  10. c# 结构体 集合 复习

    添加5个学生的信息到集合中,每个学生都有:学号,姓名,成绩,3个内容,添加完毕后将学生的分数从高到低排列并打印出来,使用结构体 using System; using System.Collectio ...