定义
- 一个或多个观察者对目标的状态感兴趣,它们通过将自己依附在目标对象上以便注册所感兴趣的内容。
- 目标状态发生改变并且观察者可能对这些改变感兴趣,就会发送一个通知消息,调用每个观察者的更新方法。
- 当观察者不再对目标感兴趣的时候,它们可以简单的将自己从中分离。
组成角色
- 抽象目标角色(AbstractSubject)
- 抽象观察者角色(AbstractObserver)
- 具体目标角色(ConcreteSubject)
- 具体观察者角色(ConcreteObserver)
其中,
抽象目标角色:把所有的观察者对象保存到集合中,其中包含多个观察者,同时提供增加和删除观察者的接口;
抽象观察者角色:为具体观察者角色定义一个更新自己的接口;
具体目标角色:当目标角色内部状态发生改变的时候,给所有登记过的具体观察者发送通知消息;
具体观察者角色:实现抽象观察者定义的更新自己的接口;
从网上找到的图,希望加深理解
代码实现
核心思路:
- 定义观察者列表专门用来保存观察者角色;
- 用function实现抽象角色;
- 用prototype实现具体角色;
- 目标角色要先加入观察者角色,才能删除;
实现代码:
- 观察者列表
/**
* 观察者列表
* @constructor
*/
function ObserverList() {
this.observerList = [];
};
ObserverList.prototype.Add = function (obj)
{
return this.observerList.push(obj);
};
ObserverList.prototype.Empty = function (obj)
{
this.observerList = [];
};
ObserverList.prototype.Count = function ()
{
return this.observerList.length;
};
ObserverList.prototype.Get = function (index)
{
if (index > -1 && index < this.observerList.length)
return this.observerList[index];
};
ObserverList.prototype.Insert = function (obsj, index)
{
var pointer = -1;
if (index === 0)
{
this.observerList.unshift(obsj);
pointer = index;
}
else if (index === this.observerList.length)
{
this.observerList.push(obsj);
pointer = index;
}
return pointer;
};
ObserverList.prototype.IndexOf = function(obj, startIndex)
{
var i = startIndex,
pointer = -1;
while (i < this.observerList.length)
{
if (this.observerList[i] === obj)
{
pointer = i;
}
i ++;
}
return pointer;
};
ObserverList.prototype.RomoveIndexAt = function (index) {
if (index === 0)
this.observerList.shift();
else if(index === this.observerList.length - 1)
this.observerList.pop();
};
function extend(obj, extention)
{
for (var key in obj)
{
extention[key] = obj[key];
}
}
- 抽象目标角色/具体目标角色
function Subject()
{
this.observers = new ObserverList();
};
Subject.prototype.AddObserver = function (observer) {
this.observers.Add(observer);
};
Subject.prototype.RemoveObserver = function (observer) {
this.observers.RomoveIndexAt(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);
}
};
- 抽象观察者角色/具体观察者角色
function Observer()
{
};
Observer.prototype.Update = function (str) {
console.log(this.name + "," + str);
};
Observer.prototype.SetName = function (name) {
this.name = name;
};
- 主函数
var subject = new Subject();
var observer1 = new Observer();
observer1.SetName("Li");
var observer2 = new Observer();
observer2.SetName("Wang");
subject.AddObserver(observer1);
subject.AddObserver(observer2);
subject.Notify("I have something to say...");
console.log("----------------------------");
subject.RemoveObserver(observer1);
subject.Notify(",but now, I just love you...");
输出结果