本文提出了另一种可以构建你的程序的方法,它的灵感来自Elixir的管道宏’|>’,此方法就是使用我最近编写的小型epipe库,而不用令人可怕的parse transforms。 Epipe本身的灵感来源于Scott Wlaschin发表的这篇文章。
准备开始
我们来执行一个小实践任务,它将演示这种铁路方式的函数式编程方法。
考虑一下我们使用Erlang构建POP3电子邮件客户端的情况。 我们的目标是实现与POP服务器建立连接的控制流程。
下图说明完成此操作所需的步骤:
首先,让我们写一个函数来实现建立连接的功能:
|
|
上述代码非常漂亮,仅仅四行就完成了我们想要的功能。但是等等……上面的实现是非常完美的场景。 显然我们需要添加一些错误处理来应对边界条件的场景 :( 。我的意思是,“可能会出错的地方”?
增加错误处理
让我们总结如下图中所有可能的边界情况:
我们增加错误处理的代码,然后看看代码变成什么样子!
剧透:下面的例子很简单,可以通过将操作分成单独的函数来美化,但是嵌套的case语句是不可避免的。
|
|
现在我们添加了所有的错误处理代码。但是,代码的大小增加了400 %……可读性也相应降低了!
也许有一个更清晰的方式来实现这一点?
用“铁路”的方法来设计更好的错误处理(理论)
铁路方法背后的想法是用铁路道岔作为模拟物来分解“每一步”功能块:
这种方法可以翻译为如下的Erlang代码:
|
|
一旦为所有需要的操作创建了两种方式( ok / error )切换分支,就可以像在铁路上一样优雅地组合它们:
所以,简单来说,确切的情况是:
在成功的情况下,所有功能(“铁路道岔”)都按顺序执行,我们沿着“成功轨道”行进。否则,我们的列车将切换到“错误轨道”,并沿该路线行驶,绕过所有其他步骤:
用“铁路”的方法来设计更好的错误处理
我们发布了一个很小的Erlang库,它简化了Erlang的“铁路道岔”分解方式。那么,考虑上面的例子,让我们来看一下如何使用Epipe实现我们的用例:
|
|
总结
与嵌套的case语句实现相比,最终的代码在代码行方面不会更小,但它确实更具可读性,使得调试和支持变得更加容易。
如果你希望看到真实的实现案例,请查看使用铁路方法执行的重构例子。
原文链接: https://www.erlang-solutions.com/blog/railway-oriented-development-with-erlang.html