观察者模型是非常普遍的一种设计模式,通常会用来在不同系统之间进行解耦
观察者模式:两种关键对象和三种关键操作
-
subject对象:提供三种基本操作方式:被订阅(注册监听方法 register),被取消订阅(移除监听方法 remove),触发事件(notify)
-
observers对象:业务逻辑执行对象,监听subject对象的调用
/*
* @Author: qiao
* @Date: 2019-06-29 11:01:53
* @Last Modified by: qiao
* @Last Modified time: 2019-07-07 20:52:58
* @Description: 练习二 完善发布订阅者模型
*/
/**
* 观察者模式:两种关键对象和三种关键操作
* 1)subject对象:提供三种基本操作方式:被订阅(注册监听方法 register),被取消订阅(移除监听方法 remove),触发事件(notify)
* 2)observers对象:业务逻辑执行对象,监听subject对象的调用
*
* 观察者模型是非常普遍的一种设计模式,通常会用来在不同系统之间进行解耦,大家谈谈在哪些地方见过发布订阅者模型
* 谈论下这种设计模式通常用来解决什么问题
*/
function Subject() {
this.observerList = [];
}
Subject.prototype.register = function(observer) {
if (!observer || !observer.handler) {
return;
}
this.observerList.push(observer);
}
Subject.prototype.remove = function(observer) {
var index = this.observerList.indexOf(observer);
this.observerList.splice(index, 1);
}
Subject.prototype.notify = function() {
var args = Array.prototype.slice.call(arguments);
this.observerList.forEach(observer => {
observer.handler && observer.handler.apply(observer, args)
});
}
function Observer(handlerfn) {
this.handler = handlerfn;
}
// 测试用例
var ob1 = new Observer(function() {
var args = Array.prototype.slice.call(arguments);
console.log('ob1 handler:', args.join(' '));
});
var ob2 = new Observer(function() {
var args = Array.prototype.slice.call(arguments);
console.log('ob2 handler:', args.join(' '));
});
var subject = new Subject();
subject.register(ob1);
subject.register(ob2);
subject.notify('hello', 'world');
subject.remove(ob1);
subject.notify('hello', 'world');
发布订阅者模式
发布订阅者模式:观察者模式的变种,实现一套自定义事件系统,observers可以订阅不同的事件,subject对象也可以通过触发不同的事件来调用不同的observers
/**
* 发布订阅者模式:观察者模式的变种,实现一套自定义事件系统,observers可以订阅不同的事件,subject对象也可以通过触发不同的事件来调用不同的observers
*/
function Subject() {
this.eventSet = {};
}
Subject.prototype.subscribe = function(event, observer) {
if (!observer || !observer.handler) {
return;
}
if (!this.eventSet[event]) {
this.eventSet[event] = [];
}
this.eventSet[event].push(observer);
}
Subject.prototype.remove = function(event, observer) {
if (!event || !this.eventSet[event]) {
return;
}
if (!observer) {
this.eventSet[event] = [];
delete this.eventSet[event];
} else {
var observers = this.eventSet[event];
var index = observers.indexOf(observer);
observers.splice(index, 1);
}
}
Subject.prototype.notify = function(event) {
if (!event || !this.eventSet[event]) {
return;
}
var args = Array.prototype.slice.call(arguments, 1);
var observers = this.eventSet[event];
observers.forEach(observer => {
observer.handler && observer.handler.apply(observer, args);
})
}
function Observer(handlerfn) {
this.handler = handlerfn;
}
// 测试用例
var ob1 = new Observer(function() {
var args = Array.prototype.slice.call(arguments);
console.log('ob1 handler:', args.join(' '));
});
var ob2 = new Observer(function() {
var args = Array.prototype.slice.call(arguments);
console.log('ob2 handler:', args.join(' '));
});
var sb = new Subject();
sb.subscribe('js', ob1);
sb.subscribe('java', ob2);
sb.notify('js', 'hello', 'javascript');