观察者模式
观察者模式是一种创建松散耦合代码的技术。它定义对象间 一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。由主体和观察者组成,主体负责发布事件,同时观察者通过订阅这些事件来观察该主体。主体并不知道观察者的任何事情,观察者知道主体并能注册事件的回调函数。
例子:
1 function Observer() { 2 this.grade = []; 3 } 4 5 Observer.prototype = { 6 subscribe: function(fun) { 7 this.grade.push(fun) 8 }, 9 publish: function(name, thisObj) { 10 var scope = thisObj || window; 11 this.grade.forEach(el => { 12 el.apply(scope, name) 13 }); 14 } 15 } 16 17 let patriarch =new Observer; 18 let up = function(child) { 19 console.log(child+":数学100分") 20 } 21 let down = function(child) { 22 console.log(child+":英语90分") 23 } 24 25 patriarch.subscribe(up); 26 patriarch.subscribe(down); 27 28 patriarch.publish('小明')
发布/订阅模式
举个例子:
生活中的买房,卖房,中介就构成了一个发布订阅者模式,买房的人,一般需要的是房源,价格,使用面积等信息,他充当了订阅者的角色
中介拿到卖主的房源信息,根据手头上掌握的客户联系信息(买房的人的手机号),通知买房的人,他充当了发布者的角色
卖主想卖掉自己的房子,就需要告诉中介,把信息交给中介发布
例子:
1 class PubSub { 2 constructor() { 3 this.subscribers = {} 4 } 5 subscribe(type, fn) { 6 if (Object.prototype.hasOwnProperty.call(this.subscribers, type)) { 7 this.subscribers[type] = []; 8 } 9 10 this.subscribers[type].push(fn); 11 } 12 unsubscribe(type, fn) { 13 let listeners = this.subscribers[type]; 14 if (!listeners || !listeners.length) return; 15 this.subscribers[type] = listeners.filter(v => v !== fn); 16 } 17 publish(type, ...args) { 18 let listeners = this.subscribers[type]; 19 if (!listeners || !listeners.length) return; 20 listeners.forEach(fn => fn(...args)); 21 } 22 } 23 24 let ob = new PubSub(); 25 ob.subscribe('add', (val) => console.log(val)); 26 ob.publish('add', 1);
发布订阅模式和观察者模式的区别:
总结:
观察者模式是松耦合的,而发布/订阅是全完解耦合的。观察者模式大多数时候是同步的,而发布-订阅模式大多数时候是异步的
缺点:
- 如果一个观察目标对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
- 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
- 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
ending。。。
欢迎大家批评指点~~~