资讯专栏INFORMATION COLUMN

JS设计模式之Obeserver(观察者)模式、Publish/Subscribe(发布/订阅)模式

荆兆峰 / 1715人阅读

摘要:观察者模式定义设计模式中对的定义一个对象称为维持一系列依赖于它观察者的对象,将有关状态的任何变更自动通知给它们。如图模式比较观察者模式则多了一个类似于话题调度中心的流程,发布者和订阅者解耦。

Obeserver(观察者)模式 定义

《js设计模式》中对Observer的定义:
一个对象(称为subject)维持一系列依赖于它(观察者)的对象,将有关状态的任何变更自动通知给它们。

《设计模式:可服用面向对象软件的基础》中对Observer的定义:
一个或多个观察者对目标的状态感兴趣,它们通过将自己依附在目标对象上以便注册所感兴趣的内容。目标状态发生改变并且观察者可能对这些改变感兴趣,就会发送一个通知消息,调用每个观察者的更新方法。当观察者不再对目标感兴趣时,他们可以简单地将自己从中分离。

下面看一个观察者模式的例子:

//观察者列表
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 ];
  }
};
ObserverList.prototype.indexOf = function(obj, startIndex) {
  var i = startIndex;
  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);
};

//目标
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);
  }
};

//观察者
function Observer(name, subject) {
  this.name = name;
  this.subject = subject;
  this.subscribe(this.subject);
}
Observer.prototype.update = function(context) {
  console.log("observer:" + this.name + " content:" + context);
}
Observer.prototype.subscribe = function(subject) {
  this.subject.addObserver(this);
}


var subject1 = new Subject();
var subject2 = new Subject();
var observer1 = new Observer("observer1", subject1);
var observer2 = new Observer("observer2", subject1);
var observer3 = new Observer("observer3", subject2);
subject1.notify("999感冒灵");
subject2.notify("999胃泰");
//observer:observer1 content:999感冒灵
//observer:observer2 content:999感冒灵
//observer:observer3 content:999胃泰

常用的场景

网页的事件绑定

Publish/Subscribe(发布/订阅)模式

下面我们来看一个发布订阅的具体实现;

var pubsub={};
        (function(q){
            var topics={},
                subUid=-1,
                subscribers,
                len;
            //发布广播事件,包含特定的topic名称和参数
            q.publish=function(topic, args){
                if(!topics[topic]){
                    return false;
                }

                subscribers=topics[topic];
                len=subscribers ? subscribers.length : 0;

                while(len--){
                    subscribers[len].func(topic, args);
                }
                return this;
            };
            q.subscribe=function(topic, func){
                if(!topics[topic]){
                    topics[topic]=[];
                }

                var token=(++subUid).toString();
                topics[topic].push({
                    token:token,
                    func:func
                });
                return token;
            };

            q.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);


        function log1(topic ,data){
            console.log(topic , data);
        }
        function log2(topic ,data){
            console.log("Topic is "+topic+" Data is "+data);
        }

        pubsub.subscribe("sss",log2);
        pubsub.subscribe("sss",log1);
        pubsub.subscribe("cccc",log2);
        pubsub.subscribe("aaa", log1);
        pubsub.publish("sss","aaaaa1");
        pubsub.publish("cccc","ssssss");
        pubsub.publish("aaa", "hahahahah");
        //sss aaaaa1
        //Topic is sss Data is aaaaa1
        //Topic is cccc Data is ssssss
        //aaa hahahahah
区别

Observer模式要求希望接收到主题通知的观察者或对象必须订阅内容改变的事件。如图:

Publish/Subscribe模式比较观察者模式则多了一个类似于话题调度中心的流程,发布者和订阅者解耦。

观察者模式更像是去咖啡店点咖啡,向店家点一杯咖啡,然后做好后店家会送过来,我和店家是直接有交互的。

发布订阅模式就像是我们微信里面订阅公众号,发布者把文章发布到这个公众号,我们订阅公众号后就会收到发布者发布的文章,我们可以关注和取消关注这个公众号。

实际应用

promise

jquery的Callback内部方法

感兴趣的小伙伴可以移步自己动手实现一个Promise

JS设计模式系列文章

JS设计模式之Obeserver(观察者)模式、Publish/Subscribe(发布/订阅)模式
JS设计模式之Factory(工厂)模式
JS设计模式之Singleton(单例)模式
JS设计模式之Facade(外观)模式
JS设计模式之Module(模块)模式、Revealing Module(揭示模块)模式
JS设计模式之Mixin(混入)模式

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/109178.html

相关文章

  • JS设计模式--Factory(工厂)模式

    摘要:对解耦是很有用对。设计模式系列文章设计模式之观察者模式发布订阅模式设计模式之工厂模式设计模式之单例模式设计模式之外观模式设计模式之模块模式揭示模块模式 工厂模式 提供一个通用的接口来创建对象 示例 //Car构造函数 function Car(option) { this.doors = option.doors || 4 this.color = option...

    UsherChen 评论0 收藏0
  • JS设计模式Singleton(单例)模式

    摘要:定义限制类的实例化次数只能是一次。如果该实例不存在的情况下,可以通过一个方法创建一个类来实现创建类的新实例,如果实例已经存在,它会简单返回该对象的引用。适用场景需要频繁实例化然后销毁的对象。频繁访问数据库或文件的对象。 定义 限制类的实例化次数只能是一次。 如果该实例不存在的情况下,可以通过一个方法创建一个类来实现创建类的新实例,如果实例已经存在,它会简单返回该对象的引用。 适用场景 ...

    SillyMonkey 评论0 收藏0
  • js设计模式察者模式发布/订阅模式

    摘要:添加获取长度获取下标通知首先我们声明一个主体类,里面包含一个观察者数组,还有一些操作方法。观察者通用声明一个更新接口,用来获取主体分发的通知。主体分发消息给观察者。 观察者模式 The Observer is a design pattern where an object (known as a subject) maintains a list of objects dependi...

    HitenDev 评论0 收藏0
  • JS 察者模式

    摘要:使用观察者模式的好处支持简单的广播通信,自动通知所有已经订阅过的对象。总的来说,观察者模式所做的工作就是在解耦,让耦合的双方都依赖于抽象,而不是依赖于具体。 1. 介绍 观察者模式又叫发布订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使得它们能够自动更新自己。 使用...

    mist14 评论0 收藏0
  • JS设计模式Mixin(混入)模式

    摘要:概念模式就是一些提供能够被一个或者一组子类简单继承功能的类意在重用其功能。示例下面通过一个简单的例子来演示这个模式混入模式的实现不指定特定方法名的时候,将后者所有的方法都添加到前者里优缺点优点有助于减少系统中的重复功能及增加函数复用。 概念 Mixin模式就是一些提供能够被一个或者一组子类简单继承功能的类,意在重用其功能。在面向对象的语言中,我们会通过接口继承的方式来实现功能的复用。但...

    caiyongji 评论0 收藏0

发表评论

0条评论

荆兆峰

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<