观察者模式 详解

定义

  • 一个或多个观察者对目标的状态感兴趣,它们通过将自己依附在目标对象上以便注册所感兴趣的内容。
  • 目标状态发生改变并且观察者可能对这些改变感兴趣,就会发送一个通知消息,调用每个观察者的更新方法。
  • 当观察者不再对目标感兴趣的时候,它们可以简单的将自己从中分离。

组成角色

  • 抽象目标角色(AbstractSubject)
  • 抽象观察者角色(AbstractObserver)
  • 具体目标角色(ConcreteSubject)
  • 具体观察者角色(ConcreteObserver)

其中,
抽象目标角色:把所有的观察者对象保存到集合中,其中包含多个观察者,同时提供增加和删除观察者的接口;
抽象观察者角色:为具体观察者角色定义一个更新自己的接口;
具体目标角色:当目标角色内部状态发生改变的时候,给所有登记过的具体观察者发送通知消息;
具体观察者角色:实现抽象观察者定义的更新自己的接口;


从网上找到的图,希望加深理解
enter image description here


代码实现

核心思路:

  1. 定义观察者列表专门用来保存观察者角色;
  2. 用function实现抽象角色;
  3. 用prototype实现具体角色;
  4. 目标角色要先加入观察者角色,才能删除;

实现代码:

  • 观察者列表
/**
 * 观察者列表
 * @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...");

输出结果
这里写图片描述


其他的博客

原型模式,建造者模式,桥接模式
工厂模式,策略模式,适配器模式

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值