`
逐行分析JS源代码
  • 浏览: 87853 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

我理解的 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来判定是否继续执行后面的操作, 除了这个功能较实用外,其它的功能个人认为不常用。

 

分享到:
评论
4 楼 hlj317 2013-06-28  
逐行分析JS源代码 写道
hlj317 写道
文章中,这句代码 var args = Array.prototype.slice.call( arguments, 1 );  在低版本的IE中并不兼容,以作者的水平,应该是一个小小失误的地方。


这个是兼容的,今天在低版本的IE里有用过,并且我看过的各框架都有用到,也都没有进行其它的兼容性处理



嗯,是我搞错了,后来我又在IE7中测试了一下,确实没问题,作者很棒~~
3 楼 逐行分析JS源代码 2013-06-28  
hlj317 写道
文章中,这句代码 var args = Array.prototype.slice.call( arguments, 1 );  在低版本的IE中并不兼容,以作者的水平,应该是一个小小失误的地方。


这个是兼容的,今天在低版本的IE里有用过,并且我看过的各框架都有用到,也都没有进行其它的兼容性处理

2 楼 hlj317 2013-06-27  
文章中,这句代码 var args = Array.prototype.slice.call( arguments, 1 );  在低版本的IE中并不兼容,以作者的水平,应该是一个小小失误的地方。
1 楼 hlj317 2013-06-27  
这么有营养的文章怎么没人关注,天地良心呀~~

相关推荐

    观察者模式学习

    除了标准实现,还有很多其他语言和框架提供了观察者模式的支持,例如在C#中,可以使用System.ComponentModel.INotifyPropertyChanged接口来实现,而在JavaScript中,可以通过事件监听器或者发布/订阅模式来实现类似...

    观察者模式最佳实践

    在"观察者模式最佳实践"中,我们可以深入理解如何高效地应用这种模式。首先,我们来了解观察者模式的基本组成部分:主题(Subject)和观察者(Observer)。主题是被观察的对象,它持有对所有观察者的引用,并负责...

    观察者模式(Observer)

    在实际开发中,很多框架和库也内置了观察者模式,如JavaScript中的EventEmitter(Node.js)、C#的事件和委托,以及Android中的BroadcastReceiver等。这些工具使得开发者可以更便捷地应用观察者模式,提高代码的可...

    Observer(观察者模式)学习源码

    在实际项目中,观察者模式可以用于各种场景,如监听用户输入、跟踪文件系统更改、处理后台任务进度更新等。通过深入理解和熟练运用Observer模式,开发者能够构建出更加灵活、响应式和易于维护的软件系统。

    观察者模式

    此外,结合现代编程语言特性,如C#中的`event`关键字和.NET框架的`EventHandler`委托,或者JavaScript中的事件监听和触发机制,观察者模式的实现更加灵活和高效。虽然本案例中没有具体的源码分析,但理解观察者模式...

    前端开源库-z-observable

    "Z-Observable"就是一个这样的开源库,专注于提供可观测性功能,它在JavaScript中实现了观察者模式,帮助开发者处理数据变化和响应式编程。 在JavaScript中,可观测(Observable)的概念源自于函数响应式编程(FRP...

    ruby、javascript、php中的观察者模式实现代码

    `Subject`类通过包含`Observable`模块,获得了观察者模式所需的方法。`Subject`类有一个`notify`方法,当状态变化时,调用这个方法通知所有观察者。`Obs`类作为观察者,实现了`update`方法来响应被观察者的通知。...

    Observer模式

    同时,还可以探索其他编程语言中对观察者模式的支持,如C#的System.ComponentModel.INotifyPropertyChanged接口,或者是JavaScript的事件监听机制。 在开发工具中,Observer模式也有广泛应用。例如,IDE(集成开发...

    js代码-最简单的观察者模式

    在“js代码-最简单的观察者模式”中,`main.js`可能是实现观察者模式的核心代码文件,而`README.txt`可能包含了关于如何使用和理解这些代码的说明。 下面我们将深入探讨观察者模式的基本概念和实现方式: 1. **...

    设计模式之Observer

    Observer模式,又称为“观察者模式”或“发布-订阅模式”,是一种行为设计模式,用于在对象之间建立一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。Observer模式...

    Javascript 设计模式系统讲解与应用

    #### 示例2:观察者模式实现 ```javascript function EventObservable() { this.observers = []; this.register = function (observer) { this.observers.push(observer); }; this.notify = function (data) {...

    javascript设计模式与开发实践源码

    观察者模式是一种行为设计模式,允许你定义一个订阅机制,可以通知多个“观察者”对象当某一事件发生时。在JavaScript中,可以使用EventEmitter类(Node.js)或发布/订阅模式来实现。 ```javascript class ...

    observer:观察者数据结构

    观察者模式(Observer Pattern)是一种行为设计模式,它允许你定义一个订阅机制,可以在对象状态改变时通知多个“观察”该对象...通过理解和应用观察者模式,开发者能够更好地构建可扩展和可维护的JavaScript应用程序。

    JavaScript_Patterns:不同JS模式(模块,单例,工厂,观察者,介体)的代码示例

    本资源"JavaScript_Patterns"提供了关于JavaScript中常见设计模式的代码示例,包括模块模式、单例模式、工厂模式、观察者模式和介体模式。以下将详细解析这些模式及其应用。 1. **模块模式**: 模块模式是...

    angular 用Observable实现异步调用的方法

    Observable 是一种设计模式,它代表了一个概念,即“可观察对象”,它可以向观察者推送数据序列,可以是单个数据值,也可以是数据流。它是一种基于推送(Push)的运行时执行模型,它可以是同步或异步地计算,并可能...

    ExtJS设计模式

    观察者模式是一种行为型设计模式,用于当一个对象的状态发生变化时通知其他对象。在ExtJS中,几乎所有组件都是可观察的对象,这意味着可以通过注册监听器来响应特定事件,实现组件间的通信。 **具体实现:** - **...

Global site tag (gtag.js) - Google Analytics