程序编程的依赖注入

kir*_*kun 11 procedural-programming dependency-injection

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

A
|
+-------------+
|             |
B1            B2
|             |
+------+      +------+
|      |      |      |
C11    C12    C21    C22
Run Code Online (Sandbox Code Playgroud)

显然,单元测试叶片功能,C11,C12,C21和C22非常简单:设置输入,调用功能,断言输出.

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

依赖注入建议B1(和B2也)可以作为随后宣布?

// Declare B1 with dependency injection for invoking C11 and C12.
int B1(int input, int (*c11)(int), int(*c12)(int));
Run Code Online (Sandbox Code Playgroud)

但是,如果我有多层呼叫,那么这种策略似乎不具备可扩展性.想象一下声明的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));
Run Code Online (Sandbox Code Playgroud)

呸!一定有更好的方法.

有时,我觉得DI和其他旨在促进模块化和易于维护的类似模式实际上会妨碍代码清晰度,并使简单编码变成无意义的抽象和复杂的间接变得复杂.

C中的大型软件项目(如Perl和Ruby)如何处理单元测试?

san*_*ole 3

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

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

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