这是我参与「第四届青训营 」笔记创作活动的的第3天
何为设计模式?
设计模式指在软件开发过程中对于遇到的常见问题的比较通用的解决方案。
常见的设计模式有外观模式、代理模式、工厂模式、单例模式、策略模式、迭代器模式、观察者模式、中介者模式、发布订阅模式、访问者模式等。
本文仅涉及观察者模式和发布订阅模式。
观察者模式
定义
被观察对象(subject)维护一组观察者(observer),当被观察对象状态改变时,通过调用观察者的update方法将这些变化通知到观察者。
实现一个观察者模式类
工作流程图如下:
根据上图的思路,我们可以尝试实现一个观察者类。
class Observer {
attr = null;
watch(target, attr) {
const that = this;
that.attr = attr;
Object.defineProperty(target, attr, {
set: function (newVal) {
that.update(this[`_${attr}`], newVal);
this[`_${attr}`] = newVal;
},
get: function () {
return this[attr];
}
});
}
update(oldVal, newVal) {
console.log(`${this.attr}属性值由${oldVal}变为${newVal}`);
}
}
const observer = new Observer();
const target = {
_a: 1
};
observer.watch(target, 'a');
target.a = 2; //a属性值由1变为2
发布订阅模式
发布订阅模式实际上是基于观察者模式的一种改造。
实现发布订阅类
以商品的到货通知为例展开实现:
class Shop {
constructor() {
this.repository = {};
}
// 订阅
$on(goods, callback) {
if (!this.repository[goods]) {
this.repository[goods] = [];
}
this.repository[goods].push(callback);
}
// 发布
$emit(goods) {
if (this.repository[goods] && this.repository[goods].length) {
this.repository[goods].forEach((cb) => cb(goods));
} else {
console.log('该商品没有客户订阅');
}
}
// 取消订阅
$removeSubscribe(goods, callback) {
if (this.repository[goods]) {
this.repository[goods] = this.repository[goods].filter(
(cb) => cb != callback
);
console.log('取消订阅成功');
}
}
// 一次性订阅
$once(goods, callback) {
let fn = (goods) => {
callback(goods);
this.$removeSubscribe(goods, fn);
};
this.$on(goods, fn);
}
}
var shop = new Shop();
shop.$on('电脑', function(goods) {
console.log(`${goods}货到啦!`);
});
shop.$once('鼠标', function(goods) {
console.log(`${goods}货到啦!`);
});
shop.$emit('电脑');
shop.$emit('鼠标');
shop.$emit('鼠标');
总结
-
这两种设计模式在前端领域有着许多应用场景,比如Vue的响应式实现;
-
观察者模式与发布订阅模式的区别在于:观察者模式是一对多关系,而发布订阅模式则是多对多关系。