我理解的 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 ...
随机推荐
- [POJ1050]To the Max
[POJ1050]To the Max 试题描述 Given a two-dimensional array of positive and negative integers, a sub-rect ...
- [BZOJ2724][Violet 6]蒲公英
[BZOJ2724][Violet 6]蒲公英 试题描述 输入 修正一下 l = (l_0 + x - 1) mod n + 1, r = (r_0 + x - 1) mod n + 1 输出 输入示 ...
- 2015安徽省赛 B.求和
题目描述 对于正整数n,k,我们定义这样一个函数f,它满足如下规律 现在给出n和k,你的任务就是要计算f(n,k)的值. 输入 首先是一个整数T,表示有T组数据 接下来每组数据是n和k(1<=n ...
- 获取oracle 表字段,表名,以及主键之类等等的信息。
获取表名: Oracle的user_talbes用于记录了用户表信息. select * from user_tables 获取某个表的字段: USER_TAB_COLS中记录了用户表的列信息.下 ...
- hdparm测试硬盘性能
<1>Centos安装hdparm测试硬盘性能 一.安装hdparm yum install hdparm -y Linux学习,http:// linux.it.net.cn 二.评估读 ...
- WebSite和WebApplication的区别
1. WebApplication(Web应用程序)和WebSite(网站)的区别:WebSite是为了兼容从ASP转过来的开发人员的习惯而存在的,用起来简单,例如:不需要创建命名控件.C#代码修改以 ...
- Rehashing
The size of the hash table is not determinate at the very beginning. If the total size of keys is to ...
- Eclipse 输入提示设置
提升eclipse工具的效率是提升开发效率很重要的一个环节,然而java函数之多你不可能完全记住.eclipse默认打个“.”号后会有相应的提示,然而这略显笨拙.只需要对eclipse进行简单的配置便 ...
- Cocos2d-x 学习资料推荐
最近在看Cocos2d-x ,官网的资料太少了,下面推荐一些比较好的教程,不断更新中. 1. cocos2d-x高级开发教程 如果你懂得objective-c 那么一定要看看这本书,这里面有许多C++ ...
- DP:Coins(POJ 1742)
用硬币换钱 题目大意:就是有面值为A1,A2,A3....的硬币,各有C1,C2,C3...的数量,问在钱数为m的范围内,能换多少钱?(不找零) 这题看名字就知道是完全背包,但是这题又有点不一样, ...