Python 在生产中从命令式转变为功能式

Python move from imperative to functional in production

我迷上了函数式编程和反应式方法。为了获得灵感和想法,我使用 Haskell and an awesome Rick Hickey article. In the python world I found for myself RxPy and funcy 库。现在我有数千行命令式代码,我想让它们发挥作用。如果一切都简化了,我有一个用于数据库的 getter 和 setter 接口以及一个像状态机一样工作的内核。这是它在伪代码上的样子:

class State(object):
    def __init__(id):
        self.data = database_interface.get_state(id)
        self.status = data['status']

    def process(self):
         if self.status == 'init':
             self.handle_init()
         elif self.status == 'request_data':
             self.handle_request_data()
         elif self.status == 'idle':
             self.handle_idle()
         # etc...


...

def on_new_message(msg):
    id = msg['id']
    state = State(id)
    state.process()

我的状态处理程序中有很多 iffor 命令式业务逻辑。我真的很尴尬如何从当前模型转变为反应性和功能性模型。这里一切都非常简单,但是有过类似经历的人会理解我。我需要关于下一步行动的建议,从想法到实践,比简单的实用程序或函数式风格的琐碎 REST api 更重要。此外,无论我在哪里获得想法,指向真正大型项目的源代码的链接都会对我很有帮助。感谢所有响应者,拥有将命令式代码移植到功能代码的真实体验。是的,我知道它不会移植代码,而是从头开始重写。同样,我需要具有大量业务逻辑的项目示例,其中涉及数据和数据突变。无论如何,谢谢你。

停止。您在生产中有数千行代码。有用。它可能是 big ball of mud,但它有效。我是 FP 的超级粉丝,我自己也写过功能性 Python 和非常实用的 JavaScript 来工作,但这让我觉得是倒退的想法。

但是,如果您无法抗拒闪亮新事物的诱惑,请一次启动一个模块。您不能那样做的建筑?这是一个 way 更大的问题。重构以首先解决该问题。然后一次一个地浏览模块。能净则净。如果您很难使模块变得纯净,请重构它们,以便您拥有一些不纯净的模块和一堆纯净的模块,而不是所有混合模块。请注意 outwardly 纯模块可以在内部使用副作用,只要它们不泄漏到模块范围之外并且调用者无法区分就可以了。现在。

现在您已经完成了,您可以逐步更改这些模块的内部实现,而不会影响程序的其余部分。尽可能尝试用通用数据结构替换自定义 类,尤其是在模块边界处。请注意,这样做会对 perf: profile!

产生负面影响

请注意,其中许多技巧与许多人认为的定义良好 面向对象 架构的最佳实践重叠(编程到接口,不要让实现细节泄露、KISS 等)。这不是巧合。

这是 Bob 叔叔的另一个 good talk for inspiration. Here's a link to clean architecture。尽管面向 UI 相关的编程。

不要 去 read/listen 然后说 "I've got to implement the hexagonal ports-and-adapters pattern with a message queue for IPC or we're doomed!"。同样,您有工作代码。仔细更改它,最好在这里和那里稍微更改一下,尊重这意味着什么(尤其是对您的用户而言)。

如果所有这些看起来都相当苛刻,那是因为我一直走在这条路上,相信我,这很痛苦。如果您不想看到您新发现的热情消失在一大堆错误报告中,那么请慢慢来,慢慢来。我有点喜欢 node.js,但做你所说的事情永远玷污了它在我雇主中的声誉,这让我搬起石头砸了自己的脚。小心点,放慢脚步,减轻痛苦。