概述:

  观察者模式也叫 “ 发布-订阅 " 模式 , 发布者发布信息是不需要考虑订阅者是谁?添加订阅者的时候也不需要通知发布者。

应用:

  最经典的就是: DOM事件

  开发过程中我们常用自定义事件也是使用的观察者模式。

场景:

  售楼处可以在发给订阅者的短信里加上房子的单价、面积、容积率等信息,订阅者接收到这些信息之后可以进行各自的处理:

var salesOffices = {}; // 定义售楼处
salesOffices.clientList = []; // 缓存列表,存放订阅者的回调函数
salesOffices.listen = function( fn ){ // 增加订阅者
this.clientList.push( fn ); // 订阅的消息添加进缓存列表
};
salesOffices.trigger = function(){ // 发布消息
for( var i = 0, fn; fn = this.clientList[ i++ ]; ){
fn.apply( this, arguments ); // (2) // arguments 是发布消息时带上的 参数
}
};

salesOffices.listen( function( price, squareMeter ){ // 小明订阅消息
  console.log( '价格= ' + price );
  console.log( 'squareMeter= ' + squareMeter );
});


创建值观察自己关注的对象的方法

var salesOffices = {}; // 定义售楼处
salesOffices.clientList = {}; // 缓存列表,存放订阅者的回调函数
salesOffices.listen = function(key, fn) {
if (!this.clientList[key]) { // 如果还没有订阅过此类消息,给该类消息创建一个缓存列表
this.clientList[key] = [];
}
this.clientList[key].push(fn); // 订阅的消息添加进消息缓存列表
};
salesOffices.trigger = function() { // 发布消息
var key = Array.prototype.shift.call(arguments), // 取出消息类型
fns = this.clientList[key]; // 取出该消息对应的回调函数集合
if (!fns || fns.length === 0) { // 如果没有订阅该消息,则返回
return false;
}
for (var i = 0, fn; fn = fns[i++];) {
fn.apply(this, arguments); // (2) // arguments 是发布消息时附送的参数
}
};
salesOffices.listen('squareMeter88', function(price) { // 小明订阅 88 平方米房子的消息
console.log('价格= ' + price); // 输出: 2000000
});
salesOffices.listen('squareMeter110', function(price) { // 小红订阅 110 平方米房子的消息
console.log('价格= ' + price); // 输出: 3000000
});
salesOffices.trigger('squareMeter88', 2000000); // 发布 88 平方米房子的价格
salesOffices.trigger('squareMeter110', 3000000); // 发布 110 平方米房子的价格

创建通用的观察者模式对象

var event = {
clientList: [],
listen: function(key, fn) {
if (!this.clientList[key]) {
this.clientList[key] = [];
}
this.clientList[key].push(fn); // 订阅的消息添加进缓存列表
},
trigger: function() {
var key = Array.prototype.shift.call(arguments), // (1);
fns = this.clientList[key];
if (!fns || fns.length === 0) { // 如果没有绑定对应的消息
return false;
}
for (var i = 0, fn; fn = fns[i++];) {
fn.apply(this, arguments); // (2) // arguments 是 trigger 时带上的参数
}
},
remove: function(key, fn) {
var fns = this.clientList[key];
if (!fns) { // 如果 key 对应的消息没有被人订阅,则直接返回
return false;
}
if (!fn) { // 如果没有传入具体的回调函数,表示需要取消 key 对应消息的所有订阅
fns && (fns.length = 0);
} else {
for (var l = fns.length - 1; l >= 0; l--) { // 反向遍历订阅的回调函数列表
var _fn = fns[l];
if (_fn === fn) {
fns.splice(l, 1); // 删除订阅者的回调函数
}
}
}
}
}; var installEvent = function(obj) {
for (var i in event) {
obj[i] = event[i];
}
}; var salesOffices = {};
installEvent(salesOffices); salesOffices.listen('squareMeter88', function(price) { // 小明订阅消息
console.log('价格= ' + price);
});
salesOffices.listen('squareMeter100', function(price) { // 小红订阅消息
console.log('价格= ' + price);
}); salesOffices.trigger('squareMeter88', 2000000); // 输出:2000000
salesOffices.trigger('squareMeter100', 3000000); // 输出:3000000

js设计模式(五)---观察者模式的更多相关文章

  1. [JS设计模式]:观察者模式(即发布-订阅者模式)(4)

    简介 观察者模式又叫发布---订阅模式,它定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知. 举一个现实生活中的例子,例如小 ...

  2. js设计模式——3.观察者模式

    js设计模式——观察者模式 /*js设计模式——.观察者模式*/ // 主题,保存状态,状态变化之后触发所有观察者对象 class Subject { constructor() { this.sta ...

  3. JS设计模式之观察者模式

    观察者模式,即发布与订阅模式,实现一对多的一种关系模式,当一种对象接受信号时其他所有依赖均有行为.我们在写code的时候总是会去自定义一些事件,这就是观察者常常使用的地方: JS中的观察者模式应用: ...

  4. js 设计模式之观察者模式

    观察者模式 又被称为“发布-订阅”模式,目的是解决主题对象和观察者之间功能的耦合性.发布者和订阅者之间是互不干扰的,没有联系的,通过观察者,当做中介,将二者联系起来. 例子:以学生和老师之间的为例 1 ...

  5. JS 设计模式五 -- 命令模式

    概念 命令模式中的命令(command) 指的是 一个执行某些待定事情的指令. 用一种松耦合的方式来设计程序,使得请求发送者和请求接收者能够消除彼此之间的耦合关系. 例子 假设html结构如下: &l ...

  6. js设计模式-观察者模式

    定义: 观察者模式又叫发布订阅模式,它定义了对象间的一种一对多的依赖关系.观察者模式让两个对象松耦合地联系在一起,虽然不太清楚彼此的细节,但这不影响他们之间的互相通信. 思路 定义一个对象,在对象中实 ...

  7. js 设计模式——观察者模式

    观察者模式 定义 观察者模式(又被称为发布-订阅(Publish/Subscribe)模式,属于行为型模式的一种,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状 ...

  8. 前端笔记之JavaScript面向对象(三)初识ES6&underscore.js&EChart.js&设计模式&贪吃蛇开发

    一.ES6语法 ES6中对数组新增了几个函数:map().filter().reduce() ES5新增的forEach(). 都是一些语法糖. 1.1 forEach()遍历数组 forEach() ...

  9. js设计模式:工厂模式、构造函数模式、原型模式、混合模式

    一.js面向对象程序 var o1 = new Object();     o1.name = "宾宾";     o1.sex = "男";     o1.a ...

  10. JS设计模式(一)

    刚入职时,看过一段时间的设计模式,似懂非懂.不知不觉过去七个月了,对JS的理解更深刻了,数据结构与算法的基础也基本上算是过了一遍了,接下来要把设计模式搞定,然后不再深层次研究JS了,而是学习前端自动化 ...

随机推荐

  1. Docker permission denied while trying to connect to the Docker daemon socket

    Problem jenkins执行docker打包的时候报错,说没有权限 docker build -t docker.ryan-miao.com/com.demo:f1aa23e --build-a ...

  2. DockerSwarm+Dubbo镜像与部署相关命令与参数

    Docker 镜像 一.容器转镜像 docker commit <containerId> <image:tag> docker commit 3ffa4284ddca zoo ...

  3. Docker查看运行中容器并进入容器

    一.简述 Docker查看运行中容器并进入容器. 二.方法 $ sudo docker ps $ sudo docker exec -it 775c7c9ee1e1 /bin/bash 将黄色文字替换 ...

  4. UseSwagger

    if [ "$UseSwagger" != "true" ]; then sed -i "s/\"UseSwagger\": tr ...

  5. Substr与mb_substr区别

      <?php $str = substr('helloword',3,4);//从下标3开始截取截取4个字符 $str = substr('helloword',3);//从截取掉前三个字符 ...

  6. 调试 lvgl 的一个例子

    发现一个新的 vector graphic 的库,用 C 写的,效果丰富,接口简单,而且是 MIT License,所以想试一试.因为它支持 framebuffer,所以,在 linux 上先走一个. ...

  7. [C#] 将NLog输出到RichTextBox,并在运行时动态修改日志级别过滤

    作者: zyl910 一.缘由 NLog是一个很好用的日志类库.利用它,可以很方便的将日志输出到 调试器.文件 等目标,还支持输出到窗体界面中的RichTextBox等目标. 而且它还支持在运行时修改 ...

  8. Spring Boot用Cxf的jax-ws开发WebService

    首先上项目的pom.xml: <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&q ...

  9. VMWare 虚机迁移后Linux系统网卡启动问题

    重新安装VMWare或拷贝虚机文件后有时网卡会无法工作,主要是因为网卡的Mac地址改变了,如果系统中的网卡配置信息中有Mac的信息,则虚机的系统的网卡可能无法正常工作. 如果出现上述问题,解决办法如下 ...

  10. animate.css做点赞效果

    花了一晚上研究出来的,感觉还行吧... 代码: 源码下载: http://image.niunan.net/animatedemo.zip