编写可维护的事件驱动代码

Man*_*tis 49 architecture documentation maintainability event-driven node.js

我刚刚开始玩事件驱动的架构,来自一个非常标准的面向对象的思维模式.

我注意到的第一件事是,理解和跟踪程序的难度似乎随着程序的大小呈指数级增长.虽然小型宠物项目很容易遵循,但感觉就像代码会迅速转向意大利面.

我理解我是这种发展思维的新手,并不是所有我的面向对象的担忧都会延续下去.有没有关于编写可维护,可理解的事件驱动代码的资源?使用node.js或Twisted或Event Machine的人对此有何看法?

sar*_*old 6

Martyn Loughran完全写了一篇关于避免回调意大利面的短篇文章.

我真的很喜欢他的文章是过程改进意大利面条到的东西非常干净的; 起初看起来有点形式化,但是当你看到最终结果时,我认为你会同意他用干净,清晰的代码表现出真正的艺术性.


Enk*_*nki 4

我将使用 Python 作为示例,因为我现在正在使用 Python 来构建大型分布式应用程序。

Twisted python 允许使用 inlinecallbacks 或(稍微难看的)deferredGenerator 样式来实现非常命令式的样式。这些方法允许您编写使用更易于阅读和理解的事件驱动回调代码的过程。该实现将您的函数转换为一个惰性序列,产生一系列延迟序列。

具体来说,您不必构建一组深度嵌套的回调函数/lambda/闭包,而是可以在任意点将函数的控制权交还给事件循环。如果您愿意,您可以在心里将其重新标记为协程或协作多任务处理。它完成了工作。一个例子是(使用丑陋的 deferredGenerator 风格),如下所示:

@defer.deferredGenerator
def foo(arg):
    bar = nonBlockingFunction(foo)
    baz = waitForDeferred(aFunctionThatReturnsADeferredToo(bar))
    yield baz #Returns control to the event loop
    output = baz.getResult() #This gets the output of aFunctionThat...Too above
    yield output #This is how we return a result instead of using return

@defer.deferredGenerator
def aFunctionThatReturnsADeferredToo(put_bar_here):
    """Stuff happens here...."""
    ...etc...
Run Code Online (Sandbox Code Playgroud)

这里还有另一篇文章展示了 inlineCallbacks 方法,该方法更干净,但需要 python 2.5 或更高版本(意味着不在 Centos/RHEL 5 系列下,遗憾的是我的应用程序一直使用它)。如果你可以使用它,就这样做。

正如您所看到的,这看起来就像您所了解和喜爱的老派 Python 命令式东西,但是无需大量嵌套函数和 lambda 就更容易维护。但我仍然希望 python 有块。

至于调试,您可以在初始化代码中使用 defer.setDebugging(True) 调用来打开扭曲反应器调试。这将附加在代码中引发异常的原始回溯,以便您可以轻松查看错误实际发生的位置。只需记住在投入生产之前编辑 setDebugging 语句,因为它会导致大量的额外内省(如果您想彻底感到震惊,请在 strace 中观看它)。