17

我正在设计一个包,我想在其中提供基于观察者模式的 API:也就是说,有些地方我想发出一个信号,触发零个或多个相关方。那些利益相关方不一定需要相互了解。

我知道我可以从头开始实现这样的 API(例如,使用通道或回调函数的集合),但想知道是否有构建此类 API 的首选方式。

在我使用过的许多语言或框架中,都有构建这些 API 的标准方法,以便它们按照用户期望的方式运行:例如,g_signal_*用于基于 glib 的应用程序、事件和addEventListener()JavaScript DOM 应用程序的函数,或用于。网。

Go有类似的东西吗?如果没有,是否有其他方式来构建这种在 Go 中更惯用的 API?

4

5 回答 5

15

我会说从通道接收的 goroutine 在一定程度上类似于观察者。因此,恕我直言,在 Go 中公开事件的一种惯用方式是从包(函数)返回通道。另一个观察结果是,回调在 Go 程序中不经常使用。原因之一,也是强者的存在select statement

最后一点:有些人(我也是)将 GoF 模式视为 Go 反模式。

于 2012-12-18T08:53:13.447 回答
4

我在几个项目中需要一个“观察者模式”类型的东西。 这是最近项目中的一个可重用示例

它有一个相应的测试来说明如何使用它。

基本理论是,Submit只要发生有趣的事情,事件发射器就会调用一些数据。任何想要了解该事件的客户端都将Register使用它读取事件数据的通道。您注册的这个通道可以select循环使用,也可以直接读取(或缓冲并轮询)。

当你完成后,你Unregister

它并不适用于所有情况(例如,我可能希望为慢速观察者提供强制注销类型的事件),但它适用于我使用它的地方。

于 2012-12-23T05:43:27.983 回答
4

Go 为您提供了许多用于设计信号 api 的工具。

首先,您必须决定几件事:

你想要推式还是拉式模型?例如。发布者是向订阅者推送事件还是订阅者从发布者那里拉取事件?

如果您想要一个推送系统,那么让订阅者为发布者提供一个发送消息的渠道会非常有效。如果你想要一个拉方法,那么只有一个用互斥锁保护的消息框就可以了。除此之外,在不了解您的要求的情况下,很难提供更多详细信息。

于 2012-12-18T21:01:56.337 回答
2

我会说没有标准的方法可以做到这一点,因为通道是内置在语言中的。没有标准的频道库,只有频道。将通道内置在一流的对象中,使您不必使用标准技术,并让您以最简单最自然的方式解决问题。

于 2012-12-19T10:42:15.693 回答
0

在https://github.com/chuckpreslar/emission有一个基本的 Golang 版本的 Node EventEmitter

http://itjumpstart.wordpress.com/2014/11/21/eventemitter-in-go/

于 2014-11-21T04:28:51.630 回答