资讯专栏INFORMATION COLUMN

[翻译] 比较不同Observer模式的实现

Hegel_Gu / 2689人阅读

摘要:使用字符串定义事件类型,容易产生拼写错误并且自动完成不能很好的工作。消息和事件的目标之间并没有关系。通过命名规范来避免消息被错误的订阅者拦截。细粒度的控制每个监听器和事件类型。倾向于使用组合而不是继承。与大多数人使用的不同。

原文链接:Comparison between different Observer Pattern implementations

下面的比较只是关于订阅、发布事件以及删除事件监听器的一些基本特性。主要是基于各种基本概念实现上的不同和它们使用上的优缺点,而不是可用的特性。有些被标记为缺点的部分可以通过“好的实现”或则“hack”来避免,但是通常情况下,这些缺点都是存在的。

所有的实现都基于一种设计模式(Observer)完成了相同的任务,他们虽然有很多共同点,但运行方式上却有些许不同。本文主要是为了帮助你选择哪种实现最适合你的工作流以及你要解决的问题种类。

Event Emitter/Target/Dispatcher

所有派发自定义事件的对象都需要继承自EventEmitter/EventTarget/EventDspatcher或者实现特定的接口。

使用字符串定义事件类型。

DOM2/DOM3 Events就是基于这样的模式。

代码示例
  myObject.addEventListener("myCustomEventTypeString", handler);
  myObject.dispatchEvent(new Event("myCustomEventTypeString"));
  myObject.removeEventListener("myCustomEventTypeString", handler);
优点

target object具有完全的控制,确保只监听特定target派发的事件。

能够派发任意的事件类型而不用修改target object。

每一种target/object/event都使用相同的方法。

代码容易理解。

事件的target通常都是object本身,这使得事件冒泡更有逻辑性。

流行。

缺点

倾向于使用继承而不是组合。

使用字符串定义事件类型,容易产生拼写错误并且IDE自动完成不能很好的工作。

Event handler通常只接受一个参数(Event Object)。

如果想传递额外的数据,必须创建一个实现了特定接口的自定义Event对象或者扩展一个基本的Event对象,这个过程通常是繁琐不便的。

Publish / Subscribe (pub/sub)

使用同一个对象向多个订阅者广播消息。

并不是必要条件,但大多数实现都使用一个静态的集中的对象作为广播者。

使用字符串定义事件类型。

消息和事件的目标之间并没有关系。

代码示例
  globalBroadcaster.subscribe("myCustomEventTypeString", handler);
  globalBroadcaster.publish("myCustomEventTypeString", paramsArray);
  globalBroadcaster.unsubscribe("myCustomEventTypeString", handler);
优点

任意对象都能订阅/发布任何事件类型。

轻量级。

容易使用/实现。

缺点

任意对象都能订阅/发布任何事件类型(是的,这既是优点也是缺点)。

使用字符串定义事件类型。

容易出错。

没有自动完成(除非将value保存为变量/常量)。

通过命名规范来避免消息被错误的订阅者拦截。

Signals

每种事件类型都有自己的控制器

事件类型不依赖于字符串。

代码示例
  myObject.myCustomEventType.add(handler);
  myObject.myCustomEventType.dispatch(param1, param2, ...);
  myObject.myCustomEventType.remove(handler);
优点

不依赖于字符串。

自动完成能正常工作。

派发或监听一个不存在的事件类型会抛出错误(能够更早的发现错误)。

不需要创建常量来存储字符串值。

细粒度的控制每个监听器和事件类型。

每个signal都是一个特定的目标/容器。

容易定义对象派发的signal。

倾向于使用组合而不是继承。

别和原型链混淆了。

缺点

不能派发任意类型的事件。(这在大多数情况下也是个优点)

每个事件类型都是个对象成员。(这在大多数情况下也是个优点)

如果有很多事件类型的话,易导致命名空间混乱。

不会将事件类型和目标对象传递给callback使得很难使用通用的handler(工作于多个事件类型和目标)。

与大多数人使用的不同。

结论

就像生活中的大多数东西一样,每种解决方案都有它的优点和缺点。决定哪种方式最适合取决于你。我希望本文能在你做决定时帮助到你。再一次,没有解决方案是万能的。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/78573.html

相关文章

  • 设计模式 -- 观察者模式

    摘要:总结一下从表面上看观察者模式里,只有两个角色观察者被观察者而发布订阅模式,却不仅仅只有发布者和订阅者两个角色,还有第三个角色经纪人存在。参考链接观察者模式发布订阅模式 做了这么长时间的 菜鸟程序员 ,我好像还没有写过一篇关于设计模式的博客...咳咳...意外,纯属意外。所以,我决定,从这一刻起,我要把设计模式在从头学习一遍,不然都对不起我这 菜鸟 的身份。那这次,就从观察者模式开始好啦...

    chengtao1633 评论0 收藏0
  • 设计模式 -- 观察者模式

    摘要:总结一下从表面上看观察者模式里,只有两个角色观察者被观察者而发布订阅模式,却不仅仅只有发布者和订阅者两个角色,还有第三个角色经纪人存在。参考链接观察者模式发布订阅模式 做了这么长时间的 菜鸟程序员 ,我好像还没有写过一篇关于设计模式的博客...咳咳...意外,纯属意外。所以,我决定,从这一刻起,我要把设计模式在从头学习一遍,不然都对不起我这 菜鸟 的身份。那这次,就从观察者模式开始好啦...

    makeFoxPlay 评论0 收藏0
  • Java设计模式学习总结

    摘要:的设计模式世界顶级足球射门锦集。重构敏捷软件开发设计模式解析一场场最精彩的足球比赛。但不属于种设计模式之一。代理设计模式代理模式,为其他对象提供一种代理以控制对这个对象的访问。 前言 编程是一门技术,更是一门艺术。如果想成为一名更优秀的软件设计师,了解优秀软件设计的演变过程比学习优秀设计本身更有价值,因为设计的演变过程中蕴藏着大智慧。学习设计模式,重要的不是你将来会不会用得到这些模式,...

    songze 评论0 收藏0
  • 同是ZooKeeper,你和架构师理解差在哪里?

    摘要:作为整个集群的主节点,负责响应所有对状态变更的请求。选举是最重要的技术之一,也是保障分布式数据一致性的关键所在。这是由于半数以上投票通过决定的。另外需要注意的是,和构成集群的法定人数,也就是说,只有他们才参与新的选举响应的提议。 showImg(https://segmentfault.com/img/remote/1460000016733126); 前言 提到ZooKeeper,相...

    sixgo 评论0 收藏0
  • 同是ZooKeeper,你和架构师理解差在哪里?

    摘要:作为整个集群的主节点,负责响应所有对状态变更的请求。选举是最重要的技术之一,也是保障分布式数据一致性的关键所在。这是由于半数以上投票通过决定的。另外需要注意的是,和构成集群的法定人数,也就是说,只有他们才参与新的选举响应的提议。 showImg(https://segmentfault.com/img/remote/1460000016733126); 前言 提到ZooKeeper,相...

    IntMain 评论0 收藏0

发表评论

0条评论

Hegel_Gu

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<