`
redhacker
  • 浏览: 489355 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JS实现监听模式和观察者模式

 
阅读更多
引子:

最近看阮一峰先生的这篇文章,文章涉及到观察模式,监听模式相关的设计模式的内容,正好,我最近也用swt做个一个视频批量上传的桌面应用,在这个桌面应用的sdk中,有大量的监听器接口,用来监听该应用的很多组件上的事件,比如按钮的点击事件、树形组件节点的选中事件,等等。我为了实现该应用,也大量应用了监听模式,譬如:文件上传进度的监听,上传列表选中行的事件监听,软件启动时log4j初始化的监听事件,等等。


在该应用开发的过程中,我曾经思考过用观察者模式,但最后为了应用代码维护的简单性,所有的事件处理,都统一使用了监听模式。实际上面提到的文件上传进度的监听,上传列表选中行的事件监听,软件启动时log4j初始化的监听事件,只有上传列表选中行的事件监听可以改为观察者模式,原因是因为选中多行时,确实要同时去更新工具栏状态和状态栏显示的信息。

为了对监听模式和观察者模式有一个复习,我回复了阮先生的博客,参考:http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html#comment-267332,回复是通过js实现一个监听模式的例子。实际上,我后来发现这个例子有一些命名上的瑕疵。本想再写一个观察者模式的例子进行回复,无奈阮先生的博客的评论功能实在是太弱了,我监听模式的例子就贴乱了,还烦劳他修改了一次。因此,我才决心写两篇博客交代一下这两个设计模式。当然了,这篇博客我只打算写两个没有什么实际场景的小例子,下篇博客,举例一个真实的场景,用java和js分别给出实现代码。

请看监听模式的代码示例:

// 事件对象
var Event = function(obj) {
	this.obj = obj;
	this.getSource = function() {
		return this.obj;
	}
}

// 监听对象
var F2 = function() {
    this.hander = function(event) {
    	var f1 = event.getSource();
    	console.log("f2 do something!");
        f1.callback();
    }
}

// 被监听对象
var F1 = function() {
	this.abc = function() {
        console.log("f1 do something one!");
        // 创建事件对象
        var e = new Event(this);
        // 发布事件
        this.f2.hander(e);
        console.log("f1 do something two!");
	}
	
	this.on = function(f2) {
	   this.f2 = f2;
	}
	
	this.callback = function() {
	   console.log("f1 callback invoke!");
	}
}

// 主函数
function main() {
    var f1 = new F1();
    var f2 = new F2();
    // 加入监听
    f1.on(f2);
    f1.abc();
}

// 运行主函数
main();


监听模式示例运行结果:
引用

f1 do something one!
f2 do something!
f1 callback invoke!
f1 do something two!



观察者模式的代码示例:

// 观察者对象1
var F2 = function() {
    this.update = function(observable, obj) {
        console.log("f2 do something!");
        for (var i=0, len=obj.length; i<len; i++) {
        	console.log(obj[i]);
        }
        observable.callback();
    }
}

// 观察者对象2
var F3 = function() {
    this.update = function(observable, obj) {
        console.log("f3 do something!");
        for (var i=0, len=obj.length; i<len; i++) {
            console.log(obj[i]);
        }
        observable.callback();
    }
}

// 被观察对象
var F1 = function() {
	// 保存所有观察者
	var observers = [];
	
    this.abc = function() {
        console.log("f1 do something one!");
        var datas = ["苹果", "桃子", "香蕉"];
        // 通知所有观察者
        this.notifyObservers(datas);
        console.log("f1 do something two!");
    }
    
    this.addObserver = function(observer) {
       observers.push(observer)
    }
    
    this.callback = function() {
       console.log("f1 callback invoke!");
    }
    
    this.notifyObservers = function(arg){
    	if (observers.length == 0) {
    	   return;
    	};
    	for (var i = 0, len = observers.length; i < len; i++) {
    		observers[i].update(this, arg);
    	}
    }
}

// 主函数
function main() {
    var f1 = new F1();
    var f2 = new F2();
    var f3 = new F3();
    // 加入观察者
    f1.addObserver(f2);
    f1.addObserver(f3);
    f1.abc();
}

// 运行主函数
main();


观察者模式示例运行结果:
引用

f1 do something one!
f2 do something!
苹果
桃子
香蕉
f1 callback invoke!
f3 do something!
苹果
桃子
香蕉
f1 callback invoke!
f1 do something two!


总结:
1、在观察者模式示例中,被观察的对象有两个观察者,因此两个观察者的逻辑被各自调用了;在监听模式示例中,被监听的对象只有一个监听者,因此只有一个监听者逻辑被调用了。监听模式示例中的监听者也可以有多个,但通知的时候需要逐一通知,比较麻烦,而观察者就方便多了,所以,当一个对象只有一个需要通知的对象时,使用监听者模式比较简单,而当需要通知的对象比较多时,采用观察者模式比较简单明了,这些要结合相应的业务场景,譬如,邮件列表的订阅就适合用观察者模式。

2、这两种模式都使用了回调的机制,唯一区别不同的是,监听模式使用一个Event对象来保留回调的钩子(事件源处传入的对象,一般是被监听者本身),而观察者模式没有抽象Event事件对象,使用参数的方式将钩子传到观察者,并附带传入了一些其他的信息。因此,观察者模式和监听者模式都是使用回调机制,其设计思想异曲同工。

3、这两种模式都是采用了对象之间组合的方式进行职责解耦,这是软件设计的指导性思想,无论我们是否很精确的实现这两种设计模式,只要在设计中把握尽量采用组合方式,我们的软件结构就会相对比较清晰,耦合度就相对比较低了,这是这两种设计模式给我们的启示!

下篇我们通过实际的例子,使用Js和Java复习一下这两种设计模式!

如果您觉得本文对您有益,请点击博文后的google广告,对作者表示支持,谢谢!
  • 大小: 31.7 KB
  • 大小: 225.1 KB
分享到:
评论

相关推荐

    javascript观察者模式Watch.JS.zip

    以往我们使用javascript实现的观察者模式都是通过使用回调函数配合dom上的event事件来操作的,而“Watch.js”可以为javascript的对象实现观察者模式,监听对象的变化。用麻雀虽小五脏俱全来描述Watch.js比较合适。...

    设计模式之观察者模式1

    设计模式之观察者模式介绍观察者模式又叫发布订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个

    原生js实现的观察者和订阅者模式简单示例

    观察者模式也叫 发布者-订阅者模式,发布者发布事件,订阅者监听事件并做出反应 在传统的前端解耦方面,观察者模式作为比较常见一种设计模式,大量使用在各种框架类库的设计当中。 核心代码: // eventProxy.js '...

    JavaScript观察者模式(publish/subscribe)原理与实现方法

    本文实例讲述了JavaScript观察者模式(publish/subscribe)原理与实现方法。分享给大家供大家参考,具体如下: 观察者模式又叫做发布订阅模式,它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这...

    javascript设计模式 – 观察者模式原理与用法实例分析

    本文实例讲述了javascript设计模式 – 观察者模式原理与用法。分享给大家供大家参考,具体如下: 介绍:前面我们针对系统内一对多,多对多的情况做了解决方案,是使用中介者模式,将所有关联关系交由中介者处理。这...

    JavaScript设计模式之观察者模式(发布订阅模式)原理与实现方法示例

    本文实例讲述了JavaScript设计模式之观察者模式(发布订阅模式)原理与实现方法。分享给大家供大家参考,具体如下: 观察者模式,又称为发布订阅模式,它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题...

    JavaScript设计模式之观察者模式实例详解

    本文实例讲述了JavaScript设计模式之观察者模式。分享给大家供大家参考,具体如下: 观察者模式 观察者模式又叫发布订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题...

    JavaScript原生实现观察者模式的示例

    观察者模式又叫做发布订阅模式,它...在JavaScript中事件监听机制就可以理解为一种观察者模式。通过onclick进行事件绑定,然后通过交互行为进行触发或者事件主动触发。 下面给出一个JS自定义的PubSub,仔细阅读下面这段

    JS设计模式之观察者模式实现实时改变页面中金额数的方法

    本文实例讲述了JS设计模式之观察者模式实现实时改变页面中金额数的方法。分享给大家供大家参考,具体如下: 观察者设计模式概念: 有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者(每...

    Javascript设计模式之观察者模式的多个实现版本实例

    介绍 观察者模式又叫发布订阅模式(Publish/Subscribe),它定义了一种一对...JS里对观察者模式的实现是通过回调来实现的,我们来先定义一个pubsub对象,其内部包含了3个方法:订阅、退订、发布。 代码如下: var pubsu

    源码分析Vue.js的监听实现教程

    相信一说到监听,当然就离不了设计模式中鼎鼎大名的观察者模式。举个例子,你家后院着火了,可一定要等到烟雾很大火光很亮你才能发现啊,可是当你安装了一个火灾预警器,当发生火灾就立马能够通知到你了。这就是一个...

    JavaScript观察者模式原理与用法实例详解

    本文实例讲述了JavaScript观察者模式原理与用法。分享给大家供大家参考,具体如下: 观察者模式 观察者模式又叫发布订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题...

    浅谈Nodejs观察者模式

    Nodejs的Events实现了一种观察者模式,其支持了Nodejs的核心机制,且http / fs / mongoose等都继承了Events,可以添加监听事件。这种设计模式在客户端的组件编程思想里经常会用到,我们先简单了解下该模式。 首次...

    深入理解Javascript中的观察者模式

    观察者模式又叫发布订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使得它们能够自动更新自己。...

    2023年高频前端vue面试题

    使用发布订阅模式将数据劫持和模板编译结合,实现双向绑定 1.observer 数据监听器,能对数据对象的所有属性进行监听,通过Object.defineProperty劫持. (vue3 proxy)将他们转化为getter/setter,如果发生数据变化会...

    watch.min.js

    您可能知道,“观察者”设计模式涉及到在观察到的对象发生更改时执行一些函数。其他库也有这样的功能,但是使用Watch.JS就不需要改变开发方式了。看一看示例,看看将Watch.JS添加到代码中有多简单。

    Node.js 事件循环详解及实例

    Node.js 基本上所有的事件机制都是用设计模式中观察者模式实现。 Node.js 单线程类似进入一个while(true)的事件循环,直到没有事件观察者退出,每个异步事件都生成一个事件观察者,如果有事件发生就调用该回调函数...

    Self-Vue:尝试自己实现vue源码(自我实现的vue源代码)

    你可以在输入框尝试双向绑定效果,你也可以在控制台修改app的message和title属性或app.data中的message和title属性来尝试数据监听效果(其中您可以使用self-vue.js来实现和vue核心一样的事情。 项目描述:自己实现的...

    微信小程序 Node.js (基础四) 事件循环& (基础五) EventEmitter

    Node.js 基本上所有的事件机制都是用设计模式中观察者模式实现。 Node.js 单线程类似进入一个while(true)的事件循环,直到没有事件观察者退出,每个异步事件都生成一个事件观察者,如果有事件发生就调用该回调函数. ...

Global site tag (gtag.js) - Google Analytics