dependency-injection - 过程编程的依赖注入(inject)

标签 dependency-injection procedural-programming

假设我决定用 C 或任何其他过程编程语言编写一个大型应用程序。它具有如下所示的调用依赖函数:

A
|
+-------------+
|             |
B1            B2
|             |
+------+      +------+
|      |      |      |
C11    C12    C21    C22

显然,对叶子函数 C11、C12、C21 和 C22 进行单元测试非常容易:设置输入、调用函数、断言输出。

但是,为 B1、B2 和 A 启用良好的单元测试的正确策略是什么?

Dependency Injection建议B1 (和 B2 也)声明如下?
// Declare B1 with dependency injection for invoking C11 and C12.
int B1(int input, int (*c11)(int), int(*c12)(int));

但是,如果我有多层调用,该策略似乎无法扩展。想象一下 A 的声明是什么看起来像:
int A(int input, int (*b1)(int, int (*)(int), int(*)(int)), 
                 int(*b2)(int, int (*)(int), int(*)(int)),
                 int (*c11)(int),
                 int (*c12)(int),
                 int (*c21)(int),
                 int (*c22)(int));

呸!一定有更好的方法。

有时,我觉得 DI 和其他旨在促进模块化和易于维护的类似模式实际上阻碍了代码的清晰度,并使应该直接编码的内容变得复杂,变成了无意义的抽象和复杂的间接。

C 语言的大型软件项目,如 Perl 和 Ruby,如何处理单元测试?

最佳答案

如果您只需要 DI 进行单元测试,您可以使用链接器来完成它。

我的意思是函数 B1 和 B2 在头文件中声明并由函数 A 使用,因此 B 函数的实现由链接器提供。您只需要为单元测试提供不同的 C 文件。这应该不是一个大问题,因为无论如何您可能都有自己的单元测试生成文件。

如果您需要在运行时进行动态依赖解析,您应该为函数指针使用工厂模式(返回函数指针的函数),并在需要时从工厂中提取它们。工厂可以根据全局上下文决定返回什么函数。

关于dependency-injection - 过程编程的依赖注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5527785/

相关文章:

php - 在没有 MVC 的情况下按程序编写一个相当大的、以数据库为中心的 PHP 应用程序是否合理?

algorithm - L 系统节点重写示例

java - 想要一个简单的代码来获取州名称和城市名称取决于选择

java - Spring 发现 beans 从版本 4.3 更改为版本 5

使用案例类/伴随对象模式时的 Scala 依赖注入(inject)

ruby - 用 Ruby 替换运行时实现

oop - API — CFC与cfinclude

functional-programming - 有状态编程的优点?

c# - 控制台应用程序中的 Autofac(约定)

c# - 使用 Unity 解析 Interface<T>