我理解的 js 的观察者模式 Observable
我第一次看 四人帮 写的《设计模式》时一头雾水,现在也是,或许其是针对专业的程序员学习使用的。
通过对Ext / Backbone 源码的学习,可总结如下:
模式 - 就是对解决某一类特定问题的有效总结,并在后续解决同样的问题可以持续使用。
设计模式 - 程序开发者认为自己是优雅的设计师。
观察者模式:主要应用于组件开发,以便组件使用者 可以自行定义某个性方法,在组件达到某种状态时调用。
一、观察者模式原理
组件开发为了保证组件可以在不同的项目中都适用,其必须是对其常用功能 抽象出来 加以实现,绝不会包含具体的业务逻辑
而某一特定的项目使用者在其业务场景中使用组件时不可避免的要加入不同场景的业务逻辑,观察者模式很好的解决了这个的问题。
如下:
- /*
- * 组件开发者A 定义了通用方法 test 供 业务开发者B 使用
- */
- function test(){
- beforeTest && beforeTest()
- // do test something
- console.log( 'test ');
- // do test something
- afterTest && afterTest();
- }
- /*
- * 业务开发者B使用test,不修改test源码的情况下,执行test时,如B需要可以先执行B自定义的方法,test执行结束后还需再执行B自定义的另一方法
- * 双方约定先执行的方法名为 beforeTest
- */
- function beforeTest(){
- console.log('beforeTest')
- /*
- * do beforeTest something
- */
- }
- /*
- * 双方约定后执行的方法名为 afterTest
- */
- function afterTest(){
- console.log('afterTest')
- /*
- * do afterTest something
- */
- }
- /*
- * 示例:
- */
- test(); //控制台会输出 开发者B自定义方法里的值 beforeTest ; afterTest
- //这样每次执行test时,都会执行B自定义的方法
通过上面这种模式,可以降低代码之间的耦合,据实际使用和双方约定,组件使用方可以在组件使用过程中,不对组件进行修改,却可以自由的定义、执行其业务需要的个性化的方法。
上面的方法只是讲了原理,并不适用于实际的项目,且对于beforeTest只能定义一个,经过简单的抽象提取如下
- /*
- * 组件开发者A定义组件 Person 供开发者B使用
- */
- var events = {
- /*
- * 添加 name 对应的 事件callback,保存在this._events里
- */
- on: function( name, callback ){
- this._events || (this._events = {}); //确保this._events存在
- this._events[name] = this._events[name] || [];//确保this._events[name]存在
- this._events[name].push({ callback: callback });//将callback 添加到 this._events[name] 内
- },
- /*
- * 执行已经保存在this._events里的 name 对应的事件
- */
- trigger : function( name ){
- var args = Array.prototype.slice.call( arguments, 1 );
- //将参数中除 name 外的其它参数取出来
- if( this._events && this._events[name] ){ //确保 this._events[name] 存在
- for( var i = 0; i < this._events[name].length; i++){
- //循环执行里面的callback
- this._events[name][i].callback.apply( this, args );
- //将步骤一取出的值作用callback的参数
- }
- }
- },
- /*
- * 删除this._events里 name 对应的事件
- */
- off: function( name ){
- if( this._events ){
- delete this._events[name]; //删除 this._events[name]
- }
- }
- }
- var Person = function( config ){
- this.name = config.name;
- this.age = config.age;
- }
- for( var key in events ){
- Person.prototype[key] = events[key];
- //将events里的属性添加到Person的原型里
- }
- Person.prototype.getName = function(){
- this.trigger('getName', this.name );
- return this.name;
- }
- /*
- * 当设置Person里的名字里,执行一次 setName 监听
- */
- Person.prototype.setName = function( name ){
- this.trigger( 'setName', name );
- this.name = name;
- return this;
- }
- /*
- * 生成一个实例
- */
- var lulu = new Person({ name: 'lulu', age: '25'});
- /*
- * 根据业务的个性化需要 添加一个监听事件,当执行到setName里,执行function,
- */
- lulu.on( 'setName', function( name ){
- console.log('您执行一次setName __ ' + name );
- /*
- * 上面一个无意义的场景
- * 实际的场景可以是setName后会通过 ajax 保存到数据库等操作
- */
- });
- /*
- * 对同一个监听行为可以添加多个 事件
- */
- lulu.on( 'setName', function( name ){
- console.log('您执行二次setName __ ' + name )
- });
- /*
- * 测试
- */
- lulu.setName('nana'); //控制台会输出 您执行一次setName __ nana; 您执行二次setName __ nana;
- lulu.setName('aobama'); //您执行一次setName __ aobama; 您执行二次setName __ aobama;
- lulu.off( 'setName' );
- lulu.setName('lala'); //此时控制台将不会再输出信息
观察者模式 基础使用就是上面所讲,不过不同的框架又在此基础上丰富了功能
如backbone,可以一次添加多个监听事件 lulu.on({ 'setName': fun1, 'getName': fun2 }); 和只执行一次的监听 once。 具体参见 【backbone 源码分析】
Ext提供的功能更多,其中可以 据每次执行监听事件的结果是否为false来判定是否继续执行后面的操作, 除了这个功能较实用外,其它的功能个人认为不常用。
来源转载:http://jiangxiao-2000.iteye.com/blog/1893601
我理解的 js 的观察者模式 Observable的更多相关文章
- 设计模式之观察者模式(Observable与Observer)
设计模式之观察者模式(Observable与Observer) 好久没有写博客啦,之前看完了<设计模式之禅>也没有总结一下,现在回忆一下设计模式之观察者模式. 1.什么是观察者模式 简单情 ...
- RxJava 设计理念 观察者模式 Observable lambdas MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- java中观察者模式Observable和Observer
25.java中观察者模式Observable和Observer 如果想要实现观察者模式,则必须依靠java.util包中提供的Observable类和Observer接口 观察者设计模式 现在很多的 ...
- 理解Node.js的事件轮询
前言 总括 : 原文地址:理解Node.js的事件轮询 Node小应用:Node-sample 智者阅读群书,亦阅历人生 正文 Node.js的两个基本概念 Node.js的第一个基本概念就是I/O操 ...
- js设计模式-观察者模式
定义: 观察者模式又叫发布订阅模式,它定义了对象间的一种一对多的依赖关系.观察者模式让两个对象松耦合地联系在一起,虽然不太清楚彼此的细节,但这不影响他们之间的互相通信. 思路 定义一个对象,在对象中实 ...
- 初步理解require.js模块化编程
初步理解require.js模块化编程 一.Javascript模块化编程 目前,通行的Javascript模块规范共有两种:CommonJS和AMD. 1.commonjs 2009年,美国程序员R ...
- 方便大家学习的Node.js教程(一):理解Node.js
理解Node.js 为了理解Node.js是如何工作的,首先你需要理解一些使得Javascript适用于服务器端开发的关键特性.Javascript是一门简单而又灵活的语言,这种灵活性让它能够经受住时 ...
- 深入理解Node.js中的垃圾回收和内存泄漏的捕获
深入理解Node.js中的垃圾回收和内存泄漏的捕获 文章来自:http://wwsun.github.io/posts/understanding-nodejs-gc.html Jan 5, 2016 ...
- 深入理解three.js中光源
前言: Three.js 是一个封装了 WebGL 接口的非常好的库,简化了 WebGL 很多细节,降低了学习成本,是当前前端开发者完成3D绘图的得力工具,那么今天我就给大家详细讲解下 Three.j ...
随机推荐
- 默认hosts后面为files dns
售后工程师 : 您好,问题已经解决,问题原因是您修改了/etc/nsswitch.conf配置文件中的hosts:这项导致的,默认hosts后面为files dns,但是后面去掉了DNS导致直接使用本 ...
- nginx 反向代理 google
nginx的反向代理,google一直都是不容易打开的,如果你有一台位于国外的vps或者服务器,就可以轻松解决这个问题,这次的主角是nginx,nginx的反向代理现在已经发展很强大了,很多时候拿他来 ...
- android dialog 模拟新浪、腾讯title弹框效果
http://blog.csdn.net/jj120522/article/details/7764183 首先我们看一下新浪微博的效果(其它就是一个dialog): 点 ...
- linux下复制一个文件的内容到另一个文件
cat path/to/file/filename1 >> path/to/file/filename2 例如: cat id_rsa.pub >> ~/.ssh/author ...
- 【云计算】实战-五个Docker监控工具的对比
[实战]五个Docker监控工具的对比 阅读目录 Docker Stats命令 CAdvisor Scout Data Dog Sensu Monitoring Framework 总结 这篇文章作者 ...
- 开博一周总结与随谈[thinking of writing blog for one week]
8天前,就是5月19号,突发奇想,觉得应该开个博客记录下自己的学习笔记和心得,更重要的是做个自我梳理和总结.大致看了下国内的博客,最后选定cnblogs.之所以选则cnblogs是因为平时搜到不少好文 ...
- php对象引用和析构函数的关系
在php中构造函数和析构函数都属于魔术方法,比如构造函数在某一个类中,当这个类被实例化的时候就会自动调用,而析构函数是在这个类的对象被销毁的时候自动调用,默认情况下是在程序执行结束时自动调用. 如果我 ...
- [MAC] SVN lock的使用
转载 : http://www.eefocus.com/czzheng/blog/12-03/245532_4ca94.html 如果压根没有锁lock,那么每个人都拥有一个本地copy,每个人都能自 ...
- java中String类型转换方法
integer to String : int i = 42;String str = Integer.toString(i);orString str = "" + i doub ...
- Android 图标添加消息提醒
实现方法: 1. 在对应的布局放置TextView或者ImageView. 2. 用Canvas在原来Icon的bitmap基础上进行绘制 3. 利用开源项目ViewBadger进行添加,很方便,而且 ...