javascript设计模式(单例模式、观察者模式、发布订阅模式、代理模式)
最近学习了一部分设计模式,个人理解可能还比较浅显。设计模式是前人根据实践总结的一些更规范的编程套路,可以按照这些思想来更合理的编写代码,提高代码的复用性,增加其可维护性,而不是随意的编写我们的代码,今后我们写代码时可以参照这些编程套路。
1.单例模式
思想:保证一个类只有一个实例,并提供一个访问它的全局访问点。实现方法:先判断实例存在与否,如果存在则直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。
2.观察者模式
思想:创建一个subject(被观察者),observer(观察者)类 ,被观察者要提供一个接受观察者的方法,被观察者更新后通知所有的观察者更新。这里看视频中举的父母和小孩的例子很形象,小孩就是被观察者,而父母就是观察者。小孩如果哭了(状态更新),父母就会接收到通知并采取相应的行动。
3.发布订阅模式
思想:个人觉得这种模式可谓前端中最常见的一种模式了,h5中webworker,postmessage,socket.io等技术,promise实现,vue中数据绑定实现,非父子组件传参等等都可以看到它的影子,和观察者模式很类似,也有的人不把这两者区分。个人觉得两者本质区别是发布订阅模式订阅者,发布者都在一个类中,发布订阅模式有个事件调度中心,借别人一张图直观表示如下:
class PubSub {
constructor () {
//订阅者对象
this.subscribers = {}
}
//订阅属性
subscribe (type, fn) {
if (!Object.prototype.hasOwnProperty.call(this.subscribers, type)) {
this.subscribers[type] = [];
}
this.subscribers[type].push(fn);
}
//取消订阅一个属性
unsubscribe (type, fn) {
let listeners = this.subscribers[type];
if (!listeners || !listeners.length) return;
this.subscribers[type] = listeners.filter(v => v !== fn);
}
//发布属性
publish (type, ...args) {
let listeners = this.subscribers[type];
if (!listeners || !listeners.length) return;
listeners.forEach(fn => fn(...args));
}
}
let ob = new PubSub();
ob.subscribe('add', (val) => console.log(val));
ob.publish('add', 1);
4.代理模式
思想:这种模式在前端中也是非常常见的了,如图片懒加载(先通过一张loading图占位,然后通过异步的方式加载图片,等图片加载好了再把完成的图片加载到img标签里面。),es6中Proxy 对象,webpack中devserver的proxy。Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。