在我的经验中,我经常在 Java 等面向对象语言中看到一些设计模式,例如访问者模式、策略模式……但在 C 等过程语言中我没有看到太多模式……我想知道那些模式存在于过程语言中吗?
最佳答案
过程语言确实有设计模式。但是由于程序方法通常被忽略,而倾向于基于类的 OOP,因此它们并未得到广泛认可。
我用 C 开发高性能软件,并且有几种重复出现的模式。因此,我将提供一些我经常看到的模式的见解。
Handlebars
这就是在过程编程中进行封装的方式。构造函数不返回结构或对象。但是一个句柄:它通常是一个不透明的指针或只是一个整数。你不能用它做任何有趣的事情,因为它只是一个数字。细节完全隐藏。但是您可以将此句柄传递给处理它的函数:
例子:
上下文
对象在过程语言中通常称为上下文。 Context 是一个结构体,它包含某个系统的状态,就像对象的成员一样。在 OOP 中你写
object.method(parameter)
.在过程式编程中你写 function(addressOfContext, parameter)
.内部函数直接使用上下文结构,而公共(public)函数只接受一个句柄,实现将其解析为实际的上下文结构。回调
或者函数指针。函数的用户传递其函数的地址以向系统添加自定义行为。这就是多态在过程编程中的实现方式。这允许编写通用函数。
一个显着的例子是 qsort C 函数。这需要一个元素数组的地址。获取一个元素有多大、数组中有多少元素以及执行比较的比较器函数。这是完全通用的实现,允许对各种数据进行排序。
设置结构
当一个函数可以通过多种方式参数化时。通常使用设置结构。
规范往往要求这些结构体默认为零填充,只填充相关成员。如果某些成员是互斥的,则将它们放在一个联合中。这种设置结构的典型例子是 WNDCLASS来自 WinAPI。
可变尺寸数据
嗯,这与其说是通用设计模式,不如说是一种 C 模式。有时对象可能持有任意大小的二进制有效载荷。这种模式通常发生在从二进制文件读取数据时,因为它可以包含多种类型的数据块。这是由这样的结构完成的。
typedef struct
{
int someData;
int otherData;
int nPayloadLength;
unsigned char payload[1];
} VariableSized;
在代码中完成了以下操作:VariableSized *vs = malloc(sizeof(VariableSized) + extraLength);
这分配的内存大于允许可变长度有效负载空间的结构。然后可以通过例如访问其第 5 个字节。 vs->payload[4]
.这样做的好处是可以一次释放整个对象
free
称呼。并且保证它在内存中有一个连续的块。因此,它比在堆中的其他地方分配相应的缓冲区更好地利用缓存。OOP 设计模式的过程对应物
在过程语言中,OOP 模式从不以它们的名字命名。所以我只能在这里猜测。
创作模式
if (!initialized) { initialize(); initialized = 1; }
在对性能不重要的地方使用模式。对于性能关键代码,根本不使用延迟加载。用户必须找到一个地方来初始化上下文。 结构模式
行为模式
do
的结构体和 undo
打回来。这些回调通常需要某种上下文来操作。并维护一系列命令以执行撤消。 malloc
和 free
. 关于design-patterns - 过程语言有设计模式吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10491175/