观察者模式(Observer)

观察者模式指的是一个对象(Subject)维持一系列依赖于它的对象(Observer),当有关状态发生变更时 Subject 对象则通知一系列 Observer 对象进行更新。

在观察者模式中,Subject 对象拥有添加、删除和通知一系列 Observer 的方法等等,而 Observer 对象拥有更新方法等等。

在 Subject 对象添加了一系列 Observer 对象之后,Subject 对象则维持着这一系列 Observer 对象,当有关状态发生变更时 Subject 对象则会通知这一系列 Observer 对象进行更新。

function Subject(){
this.observers = [];
} Subject.prototype = {
add:function(observer){ // 添加
this.observers.push(observer);
},
remove:function(observer){ // 删除
var observers = this.observers;
for(var i = 0;i < observers.length;i++){
if(observers[i] === observer){
observers.splice(i,1);
}
}
},
notify:function(){ // 通知
var observers = this.observers;
for(var i = 0;i < observers.length;i++){
observers[i].update();
}
}
} function Observer(name){
this.name = name;
} Observer.prototype = {
update:function(){ // 更新
console.log('my name is '+this.name);
}
} var sub = new Subject(); var obs1 = new Observer('ttsy1');
var obs2 = new Observer('ttsy2'); sub.add(obs1);
sub.add(obs2);
sub.notify(); //my name is ttsy1、my name is ttsy2

  

上述代码中,我们创建了 Subject 对象和两个 Observer 对象,当有关状态发生变更时则通过 Subject 对象的 notify 方法通知这两个 Observer 对象,这两个 Observer 对象通过 update 方法进行更新。

在 Subject 对象添加了一系列 Observer 对象之后,还可以通过 remove 方法移除某个 Observer 对象对它的依赖。

var sub = new Subject();

var obs1 = new Observer('ttsy1');
var obs2 = new Observer('ttsy2'); sub.add(obs1);
sub.add(obs2);
sub.remove(obs2);
sub.notify(); //my name is ttsy1

  

发布订阅模式(Publisher && Subscriber)

发布订阅模式指的是希望接收通知的对象(Subscriber)基于一个主题通过自定义事件订阅主题,被激活事件的对象(Publisher)通过发布主题事件的方式通知各个订阅该主题的 Subscriber 对象。

let pubSub = {
list:{},
subscribe:function(key,fn){ // 订阅
if (!this.list[key]) {
this.list[key] = [];
}
this.list[key].push(fn);
},
publish:function(){ // 发布
let arg = arguments;
let key = [].shift.call(arg);
let fns = this.list[key]; if(!fns || fns.length<=0) return false; for(var i=0,len=fns.length;i<len;i++){
fns[i].apply(this, arg);
} },
unSubscribe(key) { // 取消订阅
delete this.list[key];
}
}; pubSub.subscribe('name', (name) => {
console.log('your name is ' + name);
});
pubSub.subscribe('sex', (sex) => {
console.log('your sex is ' + sex);
});
pubSub.publish('name', 'ttsy1'); // your name is ttsy1
pubSub.publish('sex', 'male'); // your sex is male

  

上述代码的订阅是基于 name 和 sex 主题来自定义事件,发布是通过 name 和 sex 主题并传入自定义事件的参数,最终触发了特定主题的自定义事件。

可以通过 unSubscribe 方法取消特定主题的订阅。

pubSub.subscribe('name', (name) => {
pubSub.subscribe('name', (name) => {
console.log('your name is ' + name);
});
pubSub.subscribe('sex', (sex) => {
console.log('your sex is ' + sex);
});
pubSub.unSubscribe('name');
pubSub.publish('name', 'ttsy1'); // 这个主题被取消订阅了
pubSub.publish('sex', 'male'); // your sex is male

  

观察者模式 VS 发布订阅模式

观察者模式与发布订阅模式都是定义了一个一对多的依赖关系,当有关状态发生变更时则执行相应的更新。

不同的是,在观察者模式中依赖于 Subject 对象的一系列 Observer 对象在被通知之后只能执行同一个特定的更新方法,而在发布订阅模式中则可以基于不同的主题去执行不同的自定义事件。相对而言,发布订阅模式比观察者模式要更加灵活多变。

我认为,观察者模式和发布订阅模式本质上的思想是一样的,而发布订阅模式可以被看作是观察者模式的一个进阶版。

设计模式只是一种思想,某一种设计模式都可以有很多种不同的实现方式,各种实现都有其优劣之分,具体的实现方式需要基于不同的业务场景。上述是我对观察者模式和发布订阅模式学习之后的一些理解,望指正。

js之观察者模式和发布订阅模式区别的更多相关文章

  1. 观察者模式 vs 发布-订阅模式

    我曾经在面试中被问道,_“观察者模式和发布订阅模式的有什么区别?” _我迅速回忆起“Head First设计模式”那本书: 发布 + 订阅 = 观察者模式 “我知道了,我知道了,别想骗我” 我微笑着回 ...

  2. JS中什么是发布--订阅模式?

    转载文章部分内容: 发布订阅模式介绍 发布---订阅模式又叫观察者模式,它定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知. ...

  3. 观察者模式Vs发布订阅模式

    1)观察者模式 观察者模式通俗的讲就是我们平事件调用(click/change等等) 大家先看这个图片.我们被观察者Subject(监听某个事件)发生改变时,观察者Observer监听到没改变做出调整 ...

  4. 观察者模式 Observer 发布订阅模式 源 监听 行为型 设计模式(二十三)

    观察者模式 Observer 意图 定义对象一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖他的对象都得到通知并自动更新. 别名:依赖(Dependents),发布订阅(Publish-Su ...

  5. C#设计模式--观察者模式(发布-订阅模式)

    0.C#设计模式--简单工厂模式 1.C#设计模式--工厂方法模式 2.C#设计模式--抽象工厂模式 3.C#设计模式--单例模式 4.C#设计模式--建造者模式 5.C#设计模式--原型模式 6.C ...

  6. java设计模式之-观察者模式(发布-订阅模式)

    1.观察者模式定义  观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象. 这个主题对象在状态上发生变化时,会通知所有观察者对象,让它们能够自动更新自己. 2.观察者模式结构 ...

  7. js 最简单的发布订阅模式

    let _subscriber: any; function autorun(subscriber: Function) { _subscriber = subscriber; _subscriber ...

  8. js里的发布订阅模式及vue里的事件订阅实现

    发布订阅模式(观察者模式) 发布订阅模式的定义:它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知. 发布订阅模式在JS中最常见的就是DOM的事件绑定与触发 ...

  9. JS的发布订阅模式

    JS的发布订阅模式 这里要说明一下什么是发布-订阅模式 发布-订阅模式里面包含了三个模块,发布者,订阅者和处理中心.这里处理中心相当于报刊办事大厅.发布者相当与某个杂志负责人,他来中心这注册一个的杂志 ...

随机推荐

  1. 【RocketMQ源码学习】- 3. Client 发送同步消息

    本文较长,代码后面给了方法简图,希望给你帮助 发送的方式 同步发送 异步发送 消息的类型 普通消息 顺序消息 事务消息 发送同步消息的时序图 为了防止读者朋友嫌烦,可以看下时序图,后面我也会给出方法的 ...

  2. 源码学习系列之SpringBoot自动配置(篇二)

    源码学习系列之SpringBoot自动配置(篇二)之HttpEncodingAutoConfiguration 源码分析 继上一篇博客源码学习系列之SpringBoot自动配置(篇一)之后,本博客继续 ...

  3. CentOS安装图解(在VMware 8上安装)

    近期准备学习一下CentOS,打算先在VMware上装一个用于初步了解. 整体步骤如下: 一.获取CentOS安装镜像.可以从以下几个地方获取,顺便提一句,我是从163下载的. 1.CentOS的官方 ...

  4. 做HTML静态页面时遇到的问题总结

    1. 如果所示,问题:“首页”和“闲置”文字部分位于table中部 解决方法:需要取消vertical-align:middle属性,将其设置为vertical-align:top,并将文本的高度改为 ...

  5. django_2:模板

    使用模板变量: 在html文件中,{{title}}即为模板变量, 在view.py文件中,render函数,增加第三个参数,以字典形式给值. def index(req): return rende ...

  6. 虚拟机和容器docker

    云计算中最主要的技术就是虚拟机,开源虚拟机已经kvm已经集成到Linux内核!针对虚拟机浪费资源(CPU.内存.存储等)较大的缺陷,google力推Docker容器和容器管理平台Kubernetes. ...

  7. 在lldb调试中调用c++函数 - 如何使用QuartzCore里面的日志消息

    承接上一篇,上一篇讲到可以在lldb调试中调用QuartzCore.framework里的CA::Render::Object::show方法来是观察CA::Render模块内的类的信息,但是在lld ...

  8. [springboot 开发单体web shop] 8. 商品详情&评价展示

    上文回顾 上节 我们实现了根据搜索关键词查询商品列表和根据商品分类查询,并且使用到了mybatis-pagehelper插件,讲解了如何使用插件来帮助我们快速实现分页数据查询.本文我们将继续开发商品详 ...

  9. 装饰者模式学习:模拟咖啡馆的点单系统来剖析装饰者模式的使用 + 装饰者模式在java I/O 中的应用

    通过模拟咖啡馆的点单系统来剖析装饰者模式的使用 参考:https://blog.csdn.net/gududedabai/article/details/81989196 一).传统的点单系统构建,每 ...

  10. 手把手教学h5小游戏 - 贪吃蛇

    简单的小游戏制作,代码量只有两三百行.游戏可自行扩展延申. 源码已发布至github,喜欢的点个小星星,源码入口:game-snake 游戏已发布,游戏入口:http://snake.game.yan ...