前言
我建议很多人着急去了解某些框架源码的人,自己要做好一定的知识储备,先把基础做好,再去解读人家源码,否则你只会盲目的崇拜(因为人家写的太好,但你看不懂人家写的东西),然后收藏起来,从而一篇篇好文章被打入你的冷宫。
我们知道前端MVVM框架最核心的内容是其响应式系统。想要完全解读整个响应式系统,就必须要了解其中涉及的到发布者与订阅者设计模式。
同样在Java中,我们一般用该设计模式来实现消息队列。
该文章并不去研究响应式系统的实现,也不研究消息队列的实现。只是在语言层面上给刚入坑的孩子们的启示例子。
什么是 发布者与订阅者?
这种设计模式,简单的说,例如我们在微信中关注过的订阅号。那该订阅号我们可以称为发布者,我们每个订阅者(关注该订阅号的微信)可以称为订阅者。每当该订阅号发布消息的时候,并不是发送给所有微信用户,而是会选择所有订阅该订阅号的微信用户。
用代码来解释下,我们需要两个角色
-
发布者
添加订阅 (我们所谓的关注其订阅号)
移除订阅 (我们取消关注该订阅号)
通知订阅者 (订阅号发布消息,所有关注者都会收到) -
订阅者
接收消息 (接收订阅号发布的消息)
订阅者注册
![](https://img.haomeiwen.com/i1119841/b58df6597b8965d6.png)
发布者发布消息
![](https://img.haomeiwen.com/i1119841/da11c7faa89b794e.png)
了解以上关系后,我们来用最少的代码,用JS和JAVA分别来实现一下这个设计模式吧。
JavaScript最简单实现
// 微信订阅号 -- 发布者
class Dep {
constructor(name) {
// 订阅号名字
this.name = name
// 该订阅号内存的订阅者
this.subs = []
}
// 添加订阅者
addSub(sub) {
this.subs.push(sub)
}
// 发布消息通知所有订阅者
notifySubs(notifyInfo) {
this.subs.forEach((sub) => {
sub.receiveInfo(notifyInfo)
})
}
}
// 微信号 -- 订阅者
class Sub {
constructor(name) {
// 微信用户名字
this.name = name
}
// 接收订阅号发布的消息
receiveInfo(notifyInfo) {
console.log('尊敬的' + this.name + ', ' + notifyInfo)
}
}
// Test
let d1 = new Dep('王者荣耀订阅号')
let d2 = new Dep('腾讯棋牌订阅号')
let s1 = new Sub('小雪')
let s2 = new Sub('小黑')
let s3 = new Sub('小白')
// 王者荣耀订阅号添加订阅者
d1.addSub(s1)
d1.addSub(s2)
// 腾讯棋牌订阅号添加订阅者
d2.addSub(s2)
d2.addSub(s3)
// 王者荣耀订阅号发布消息
d1.notifySubs('王者荣耀更新了,快来围观啊!')
console.log('============')
// 腾讯棋牌订阅号发布消息
d2.notifySubs('腾讯棋牌有新玩法了,快来围观啊!')
以上会看到 每个订阅号发布消息后,会发给对应的订阅者。
![](https://img.haomeiwen.com/i1119841/da8bf664acd067b8.png)
我相信移除你会写吧?
Java 的最简单实现
import java.util.ArrayList;
// 微信订阅号 -- 发布者
class Dep {
private String name;
private ArrayList<Sub> subs = new ArrayList<Sub>();
public Dep(String name) {
this.name = name;
}
// 添加订阅者
public void addSub (Sub sub) {
subs.add(sub);
}
// 发布消息通知所有订阅者
public void notifySubs (String notifyInfo) {
for (Sub sub : subs) {
sub.receiveInfo(notifyInfo);
}
}
}
// 微信号 -- 订阅者
class Sub {
private String name;
public Sub (String name) {
this.name = name;
}
// 接收订阅号发布的消息
public void receiveInfo (String notifyInfo) {
System.out.println("尊敬的" + this.name + ", " + notifyInfo);
}
}
public class TestDepAndSub {
public static void main (String[] args) {
Dep d1 = new Dep("王者荣耀订阅号");
Dep d2 = new Dep("腾讯棋牌订阅号");
Sub s1 = new Sub("小雪");
Sub s2 = new Sub("小黑");
Sub s3 = new Sub("小白");
// 王者荣耀订阅号添加订阅者
d1.addSub(s1);
d1.addSub(s2);
// 腾讯棋牌订阅号添加订阅者
d2.addSub(s2);
d2.addSub(s3);
// 王者荣耀订阅号发布消息
d1.notifySubs("王者荣耀更新了,快来围观啊!");
System.out.println("============");
// 腾讯棋牌订阅号发布消息
d2.notifySubs("腾讯棋牌有新玩法了,快来围观啊!");
}
}
同样我们也得到了相应的结果。
![](https://img.haomeiwen.com/i1119841/663378a1c5270392.png)
总结
框架源码肯定要看的,但我们不要忘了,我们为什么去看源码,不是为了跟风看而看,也不要越过自己的技术底线去看,脚踏实地一步一步来,掌握好每一个基础知识点,再去阅读源码吧,你会事半功倍的。
初学者可以关注下,以后会更新适合初学者的入门文章,循序顿进讲解下Vue的运行机制和原理。
网友评论