微信和QQ这么多群,该如何管理好友关系?
本文节选自《设计模式就该这样学》
1 中介者模式的应用场景
在现实生活中,中介者的存在是不可缺少的,如果没有了中介者,我们就不能与远方的朋友进行交流。各个同事对象将会相互进行引用,如果每个对象都与多个对象进行交互,则会形成如下图所示的网状结构。
从上图可以看到,每个对象之间都过度耦合,这样既不利于信息的复用也不利于扩展。如果引入中介者模式,则对象之间的关系将变成星形结构,如下图所示。
从上图可以看到,使用中介者模式后,任何一个类的变化,只会影响中介者和类本身,不像之前的设计,任何一个类的变化都会引起其关联的所有类的变化。这样的设计大大减少了系统的耦合度。
其实日常生活中我们每天都在刷的朋友圈,就是一个中介者。还有我们所见的信息交易平台,也是中介者模式的体现。
中介者模式是用来降低多个对象和类之间的通信复杂性的。这种模式通过提供一个中介类,将系统各层次对象间的多对多关系变成一对多关系,中介者对象可以将复杂的网状结构变成以中介者为中心的星形结构,达到降低系统的复杂性、提高可扩展性的作用。
若系统各层次对象之间存在大量的关联关系,即层次对象呈复杂的网状结构,如果直接让它们紧耦合通信,会使系统结构变得异常复杂,且当其中某个层次对象发生改变时,则与其紧耦合的相应层次对象也需进行修改,系统很难进行维护。
简单地说,如果多个类相互耦合,形成了网状结构,则考虑使用中介者模式进行优化。总结一下,中介者模式主要适用于以下应用场景。
(1)系统中对象之间存在复杂的引用关系,产生的相互依赖关系结构混乱且难以理解。
(2)交互的公共行为,如果需要改变行为,则可以增加新的中介者类。
2 中介者模式的UML类图
中介者模式的UML类图如下图所示。
3 使用中介者模式设计群聊场景
假设我们要构建一个聊天室系统,用户可以向聊天室发送消息,聊天室会向所有用户显示消息。实际上就是用户发信息与聊天室显示的通信过程,不过用户无法直接将信息发给聊天室,而需要将信息先发到服务器上,然后服务器再将该消息发给聊天室进行显示,具体代码如下。首先创建User类。
public class User {
private String name;
private ChatRoom chatRoom;
public User(String name, ChatRoom chatRoom) {
this.name = name;
this.chatRoom = chatRoom;
}
public void sendMessage(String msg) {
this.chatRoom.showMsg(this, msg);
}
public String getName() {
return name;
}
}
然后创建ChatRoom类。
public class ChatRoom {
public void showMsg(User user, String msg) {
System.out.println("[" + user.getName() + "] :" + msg);
}
}
最后编写客户端测试代码。
public static void main(String[] args) {
ChatRoom room = new ChatRoom();
User tom = new User("Tom",room);
User jerry = new User("Jerry",room);
tom.sendMessage("Hi! I am Tom.");
jerry.sendMessage("Hello! My name is Jerry.");
}
运行结果如下图所示。
4 中介者模式在JDK源码中的应用
首先来看JDK中的Timer类。打开Timer的结构,我们发现Timer类中有很多schedule()重载方法,如下图所示。
任意点开其中一个方法,我们发现所有方法最终都调用了私有的schedule()方法,源码如下。
public class Timer {
...
public void schedule(TimerTask task, long delay) {
if (delay < 0)
throw new IllegalArgumentException("Negative delay.");
sched(task, System.currentTimeMillis()+delay, 0);
}
...
private void sched(TimerTask task, long time, long period) {
if (time < 0)
throw new IllegalArgumentException("Illegal execution time.");
if (Math.abs(period) > (Long.MAX_VALUE >> 1))
period >>= 1;
synchronized(queue) {
if (!thread.newTasksMayBeScheduled)
throw new IllegalStateException("Timer already cancelled.");
synchronized(task.lock) {
if (task.state != TimerTask.VIRGIN)
throw new IllegalStateException(
"Task already scheduled or cancelled");
task.nextExecutionTime = time;
task.period = period;
task.state = TimerTask.SCHEDULED;
}
queue.add(task);
if (queue.getMin() == task)
queue.notify();
}
}
...
}
而且,不管是什么样的任务都被加入一个队列中按顺序执行。我们把这个队列中的所有对象都称为“同事”。同事之间的通信都是通过Timer来协调完成的,Timer承担了中介者的角色。
关注微信公众号『 Tom弹架构 』回复“设计模式”可获取完整源码。
本文为“Tom弹架构”原创,转载请注明出处。技术在于分享,我分享我快乐!
如果本文对您有帮助,欢迎关注和点赞;如果您有任何建议也可留言评论或私信,您的支持是我坚持创作的动力。关注微信公众号『 Tom弹架构 』可获取更多技术干货!
微信和QQ这么多群,该如何管理好友关系?的更多相关文章
- 微信、QQ群短文本聊天语料总结
在文本分类任务中,语料的特性千差万别,我们需要找到适合模型并抓住数据的特性,最终才能得到较好的model.最近在文本类别标注任务,就是给文本打标签确定该文本的类别.这是一个很费人工的过程,需要认真仔细 ...
- 为什么我们不应该使用微信或者 QQ 作为团队协作的 IM 工具?
如果你的团队没有觉得微信是低效的团队 IM 工具,那只有两种可能: 团队成员很少使用微信进行私人的生活和娱乐. 你就是一个低效的团队,而且还不自知. 本文内容 微信,连接一切 每个人都有微信 微信,低 ...
- 支付宝、微信、QQ 收款二维码三合一
最近折腾了一下合并收款码,简单记录一下折腾的过程,方法不唯一,只是提供一种思路,如果各位大佬有更加简单粗暴的办法,那就更好了. 原理 首先解析出三个二维码的内容,用 Nginx 判断 User age ...
- Android 高仿微信(QQ)滑动弹出编辑、删除菜单效果,增加下拉刷新功能
不可否认,微信.QQ列表的滑动删除.编辑功能着实很经典(从IOS那边模仿过来的),然.Android这边,对列表的操作,其实大多还停留上下文菜单来实现. Android如何实现list item的滑动 ...
- React Native 接入微博、微信、QQ 登录功能
在 App 开发中我们经常需要在用户登录模块接入 SNS 登录组件,这样会大大提高用户的注册体验.特别当一个不是刚性需求 App 推广的时候,这样会很大的降低用户体验的成本,没有人愿意忍受输入邮箱.手 ...
- app分享时判断手机是否已安装微信或QQ客户端
/** * 判断 用户是否安装微信客户端 */ public static boolean isWeixinAvilible(Context context) { final PackageManag ...
- ShareSDK集成微信、QQ、微博分享
1.前言 为什么要使用第三方的作为集成分享的工具呢?而不去用官方的呢?有什么区别么? 一个字"快",如果你使用官方的得一个个集成他们的SDK,相信这是一个痛苦的过程. 2.准备需要 ...
- 微信、QQ这类IM App怎么做——谈谈Websocket
前言 关于我和WebSocket的缘:我从大二在计算机网络课上听老师讲过之后,第一次使用就到了毕业之后的第一份工作.直到最近换了工作,到了一家是含有IM社交聊天功能的app的时候,我觉得我现在可以谈谈 ...
- 微信、QQ和手机号之间不得不说的故事!
发文字,发图片,发心情,视频聊天,查看附近的人,微信能干的事情QQ都可以,那么它们有什么区别,我QQ用得好好的为什么要我联系人都导到微信去?我们很早就有了QQ,但是在QQ时代,我们虽然用QQ发消息聊天 ...
随机推荐
- Serverless 如何在阿里巴巴实现规模化落地?
作者 | 赵庆杰(卢令) 来源 | Serverless 公众号 一.Serverless 规模化落地集团的成果 2020 年,我们在 Serverless 底层基建上做了非常大的升级,比如计算升级到 ...
- 2021-06-27 & 2021-06-28 集训题解
西克 题目传送门 Description Solution 跟 2021年省选A卷D2T1 一模一样,懒得讲了 不过这个题似乎有点卡空间,所以卡不过去 Code #include <bits/s ...
- L1-023 输出GPLT (20 分) java题解 GPLT天梯赛防坑技巧
上题目先 给定一个长度不超过10000的.仅由英文字母构成的字符串.请将字符重新调整顺序,按GPLTGPLT....这样的顺序输出,并忽略其它字符.当然,四种字符(不区分大小写)的个数不一定是一样多的 ...
- python常用内置函数(转载)
1. 和数字相关 1.1 数据类型 1.2 进制转换 1.3 数学运算 2. 和数据结构相关 2.1 序列 2.2 数据集合 2.3 相关内置函数 3. 和作用域相关 4. 和迭代器生成器相关 5. ...
- DevOps 时代的高效测试之路
10 月 22 日,2021 届 DevOps 国际峰会在北京顺利召开,来自国内外的顶级技术专家共同畅谈 DevOps 体系与方法.过程与实践.工具与技术.CODING 测试及研发流程管理产品总监程胜 ...
- 2021.9.7考试总结[NOIP模拟49]
T1 Reverse $BFS$暴力$O(n^2)$ 过程中重复枚举了很多点,考虑用链表记录当前点后面可到达的第一个未更新点. 搜索时枚举翻转子串的左端点,之后便可以算出翻转后$1$的位置. $cod ...
- 华为HG255D挂卡中继专用旋风科技固件
正的挂卡不掉线不掉速,稳定上网看上去好像很NB的样子 挂卡设置教程:http://picimg.lshou.com/pic/clou ... /6/t/1/30247515.mp4 固件链接: htt ...
- 用STM32内置的高速ADC实现简易示波器
做一个数字采样示波器一直是我长久以来的愿望,不过毕竟这个目标难度比较大,涉及的方面实在太多,模拟前端电路.高速ADC.单片机.CPLD/FPGA.通讯.上位机程序.数据处理等等,不是一下子就能成的,慢 ...
- AXI协议中的模棱两可的含义的解释(Cachable和Bufferable)
转载:https://blog.csdn.net/hit_shaoqi/article/details/53243173 Cachable和Bufferable 一个Master发出一个读写的requ ...
- AtCoder Regular Contest 128 部分题题解
关于鄙人罚坐两小时那件事...该开始看A题,这不就是个DP记录路径吗?Wrong了,嗯,我没用double,又Wrong,怎么回事,使劲检查自己的算法和细节问题,一个小时过去了,...这没错啊,又反复 ...