引子:
最近看阮一峰先生的
这篇文章,文章涉及到观察模式,监听模式相关的设计模式的内容,正好,我最近也用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实现的观察者模式都是通过使用回调函数配合dom上的event事件来操作的,而“Watch.js”可以为javascript的对象实现观察者模式,监听对象的变化。用麻雀虽小五脏俱全来描述Watch.js比较合适。...
下面将详细探讨观察者模式的概念、工作原理以及如何在JavaScript中实现。 **观察者模式的基本概念** 观察者模式是一种行为设计模式,它允许你定义一个订阅机制,可以发布事件到多个订阅者,即观察者。这些观察者会...
此外,现代前端框架如React和Vue.js也利用类似的观察者模式实现组件间的通信和状态管理。 总之,掌握观察者模式可以帮助我们构建更加灵活、可扩展的系统,提高代码的复用性和可维护性。通过最佳实践的学习,可以...
除了标准实现,还有很多其他语言和框架提供了观察者模式的支持,例如在C#中,可以使用System.ComponentModel.INotifyPropertyChanged接口来实现,而在JavaScript中,可以通过事件监听器或者发布/订阅模式来实现类似...
在JavaScript中,我们可以创建一个`pubsub`对象来实现观察者模式。`pubsub`对象包含三个主要方法:`subscribe`(订阅)、`unsubscribe`(退订)和`publish`(发布)。`subscribe`方法用于注册回调函数到特定主题...
接下来,我们将详细介绍如何使用JavaScript的`Proxy`对象和`Reflect` API来实现观察者模式。 ##### 3.1 使用`Proxy`和`Reflect` 在JavaScript中,`Proxy`对象提供了一种方式来拦截和自定义基本操作。结合`Reflect`...
在JavaScript中,我们可以使用函数、事件监听器或者发布/订阅模式来实现观察者模式。例如,HTML DOM事件就是一个观察者模式的实例,当我们为DOM元素绑定点击事件时,实际上是注册了一个监听器,当点击事件发生时,...
以上就是JavaScript中的面向对象编程思想,以及单例模式、工厂模式和观察者模式的简单实现。理解并熟练运用这些设计模式,能帮助开发者编写出更加高效、可维护的代码。在实际项目中,根据需求灵活组合和应用这些模式...
观察者模式,也被称为发布订阅...在JavaScript中,通过事件机制可以方便地实现观察者模式,从而实现高效、灵活的代码结构。无论是简单的按钮点击事件,还是复杂的业务逻辑交互,观察者模式都能提供一种优雅的解决方案。
在JavaScript中,`EventEmitter`是Node.js中的一个核心模块,它是实现观察者模式的一个典型例子。开发者可以通过`.on()`方法订阅事件,通过`.emit()`方法触发事件并通知所有订阅者。此外,`CustomEventTarget`接口在...
虽然Vue的响应式系统和传统的观察者模式有所不同,它更加专注于数据驱动而非事件驱动,但两者都是为了实现实时的、自动化的状态同步。在某些库或框架中,如RxJS,观察者模式更为直接地体现在流式数据处理和事件订阅...
在Java中,`java.util.Observable` 类和 `java.util.Observer` 接口提供了一个实现观察者模式的基础框架。当被观察的对象(Subject)状态改变时,它会调用 `notifyObservers()` 方法,将变化通知给所有注册的观察者...
此外,许多现代编程语言和框架,如JavaScript的事件监听、C#的委托和事件、Android的BroadcastReceiver,都采用了观察者模式的思想。 总之,观察者模式是一种强大的设计工具,它使得对象之间的交互更加灵活,同时...
- **响应式编程**:在函数式编程和React等库中,观察者模式常用于实现组件之间的状态同步。 ObserverJS库的实现可能会考虑性能优化,比如使用发布-订阅(Pub/Sub)模型来减少不必要的通知,或者使用惰性求值来延迟...
- 观察者模式:定义对象间的一种一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。 - 代理模式:为其他对象提供一种代理以控制对这个对象的访问。 - 原型模式:利用原型...
例如,我们可以通过定义一个通用的Events对象来提供添加监听器和触发事件的方法,使任何对象都能轻松地实现观察者模式。 总而言之,观察者模式是一个非常有用的模式,可以极大地提高系统的可扩展性和可维护性。通过...
在JavaScript中实现观察者模式的一个典型例子是DOM事件。当DOM元素上绑定了事件监听器时,当事件发生(如点击事件),就会触发绑定到该事件的处理函数。这里的DOM元素相当于目标,事件监听器相当于观察者。 在提供...
在本项目"赵云要格斗"中,开发者使用了观察者模式来实现游戏中的事件处理和对象间的通信,使得代码结构更加清晰,易于维护。观察者模式是设计模式中的一种,它定义了对象之间的一对多依赖关系,当一个对象的状态发生...
在JavaScript中,观察者模式通常表现为事件监听和回调函数的使用。 1. **观察者模式的概念** 观察者模式有时被称为发布-订阅模式,其中"观察者"负责收集多个"目标"的状态变化,并在这些变化发生时通知它们的订阅者...
此外,结合现代编程语言特性,如C#中的`event`关键字和.NET框架的`EventHandler`委托,或者JavaScript中的事件监听和触发机制,观察者模式的实现更加灵活和高效。虽然本案例中没有具体的源码分析,但理解观察者模式...