Lua:我可以将“require”用作依赖注入的形式吗?

3
我正在设计一种医院集成系统,该系统从各个医院(我们的客户)消耗数据,然后根据从数据库读取的配置应用特定的业务规则。如果我使用Java,我的第一反应将是构建一系列表示各种业务规则的接口,然后注入具体实例(使用Spring / guice)以组合一个完全配置的对象。这将使我能够在配置逻辑(对Foo医院应用什么业务规则?)和实际业务规则之间实现清晰的分离。
不幸的是,我没有使用Java,我正在使用Lua。我已经沉浸在Lua文献中几天了,最接近DI的类比似乎是使用模块。此外,似乎规定了在运行时解析lua模块的规则完全基于询问本地文件系统。
“模块模式”是实现我所追求的(配置逻辑与业务逻辑分离)的最佳/唯一方法吗?如果是,如何利用Lua的模块加载规则来在运行时变化实际加载的模块?
1个回答

11

步骤1:停止以Java程序员的思维方式思考。

你现在使用的是Lua。这里没有具有显式和编译时固定原型的类。函数是一等对象;它们是值。因此,以这种方式将问题分解。

你有一堆“规则”(即:函数)。你想将其中一些规则应用于某些数据。你有一个配置系统,该系统说:“当将规则应用于来自X位置的数据时,请使用这组规则。”所以...就这样做。

你检测到数据来自X位置。因此,你调用配置逻辑来为位置X构建一个包含要应用于该数据的规则(即:函数)的Lua表。位置X的配置逻辑从存储规则的任何位置加载规则,并将它们返回。如果配置在数据库或其他地方,则位置X的数据库条目可能会按名称引用规则。

如何将规则名称转换为实际的Lua函数由您决定,但有许多方法。你可以有一个注册表,将所有Lua文件从目录预加载到一个表中,然后根据该表中的名称选择规则。或者,你可能有一个命名的Lua文件/脚本数据库,每个文件/脚本都是单独的规则。有许多实现方式。

在Lua中,“依赖注入”只是“决定如何构建函数集合”。这不是特殊的事情,因为Lua比Java更自由形式。它只涉及函数来自哪里,如何将它们组合在一起到一个表中,然后如何将该表应用于某些数据。所有这些都由你决定。


4
如果没有依赖注入,我该如何进行单元测试?目前我正在测试一个依赖于luasocket的模块,而且我不负责集成测试。我真的很想mock luasocket对象,但我在模块的第一行就需要引用它并使用它。如果可以由其他人传递该对象会很有趣... 当然,我也可以将其作为参数传递,但这看起来很奇怪: csclient.connect('0.0.0.0','9000',require('socket')) - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接