观察者模式和发布/订阅模式
观察者模式
目标和观察者是基类,目标提供维护观察者的一系列方法,观察者提供更新接口。具体观察者和具体目标继承各自的基类,然后具体观察者把自己注册到具体目标里,在具体目标发生变化时候,调度观察者的更新方法。
观察者模式实现代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 // 1. 观察者列表
function ObserverList() {
this.observerList = [];
}
ObserverList.prototype.add = function(obj) {
return this.observerList.push(obj);
}
ObserverList.prototype.count = function() {
return this.observerList.length;
}
ObserverList.prototype.get = function(index) {
if(index > -1 && index < this.observerList.length) {
return this.observerList[index];
}
return null;
}
ObserverList.prototype.indexOf = function(obj, startIndex) {
var i = startIndex || 0;
while(i < this.observerList.length) {
if(this.observerList[i] === obj) {
return i
}
i++;
}
return -1;
}
ObserverList.prototype.removeAt = function(index) {
this.observerList.splice(index, 1);
}
// 2.目标
function Subject() {
this.observers = new ObserverList();
}
Subject.prototype.addObserver = function(observer) {
this.observers.add(observer);
}
Subject.prototype.removeObserver = function(observer) {
this.observers.removeAt(this.observers.indexOf(observer, 0));
}
Subject.prototype.notify = function(context) {
var observerCount = this.observers.count();
for(var i = 0; i < observerCount; i++) {
this.observers.get(i).update(context);
}
}
// 3.观察者
function Observer() {
this.update = function() {
//...
}
}使用范例
1
2
3 // html
// <button id="addNewObjserver">add New Observer checkBox</button>
//
发布/订阅模式
订阅者把自己想订阅的事件注册到调度中心,当该事件触发的时候,发布者发布该事件到调度中心,由调度中心同意调度订阅者注册到调度中心的处理代码。
发布/订阅模式实现代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 var pubsub = {};
(function(myObject) {
var topics = {};
var subUid = -1;
myObject.publish = function(topic, args) {
if(!topics[topic]) {
return false;
}
var subscribers = topics[topic];
var len = subscribers ? subscribers.length : 0;
while (len--) {
subscribers[len].func(topic, func);
}
return this;
};
myObject.subscribe = function(topic, func) {
if(!topics[topic]) {
topics[topic] = [];
}
var token = (++subUid).toString();
topics[topic].push({
token: token,
func: func
});
return token;
}
myObject.unsubscribe = function(token) {
for(var m in topics) {
if(topics[m]) {
for(var i = 0, j = topics[m].length; i < j; i++) {
if(topics[m][i].token === token) {
topics[m].splice(i, 1);
return token;
}
}
}
}
return this;
}
})(pubsub)
参考文档