16 procedural-programming design-patterns
根据我的经验,我经常会看到一些设计模式,比如访问者模式,策略模式......,像Java这样的面向对象语言......但我还没有看到像C这样的过程语言中有太多的模式...我想知道那些程序语言中存在哪些模式?
Cal*_*ius 30
程序语言确实有设计模式.但由于程序方法通常被忽略而偏向于基于阶级的OOP,因此它们并未得到广泛认可.
我用C开发高性能软件,并且有几种重复出现的模式.所以我会提供一些见解我经常看到的模式.
手柄
这就是在过程编程中完成封装的方式.构造函数不返回结构或对象.但是一个句柄:它通常是一个不透明的指针或只是一个整数.你不能做任何有趣的事情,因为它只是一个数字.细节完全隐藏.但是您可以将此句柄传递给处理它的函数:
例子:
上下文
对象通常在过程语言中称为上下文.Context是一个包含某个系统状态的结构,就像对象的成员一样.在你写的OOP中object.method(parameter)
.在编写程序编程时function(addressOfContext, parameter)
.内部函数直接使用上下文结构,而公共函数仅使用句柄,实现将其解析为实际的上下文结构.
回调
或函数指针.函数的用户传递其函数的地址以向系统添加自定义行为.这是多态性如何在程序编程中完成的.这允许编写通用函数.
一个值得注意的例子是qsort C函数.这将获取元素数组的地址.获取一个元素的大小以及数组中的元素数量和执行比较的比较器函数.这是完全通用的实现,允许对各种数据进行排序.
设置结构
当函数可以通过多种方式进行参数化时.通常使用设置结构.规范通常要求默认情况下这些结构为零填充,并且仅填充相关成员.如果某些成员相互排斥,则将其置于工会中.这种设置结构的典型示例是WinAPI 的WNDCLASS.
可变大小的数据
那么这是一种C模式,而不是一般的设计模式.有时,对象可能包含任意大小的二进制负载.这种模式通常在从二进制文件读取数据时发生,而不是包含几种类型的数据块.这是由像这样的结构完成的.
typedef struct
{
int someData;
int otherData;
int nPayloadLength;
unsigned char payload[1];
} VariableSized;
Run Code Online (Sandbox Code Playgroud)
在代码中完成以下操作:
VariableSized *vs = malloc(sizeof(VariableSized) + extraLength);
Run Code Online (Sandbox Code Playgroud)
这会分配比结构更大的内存,从而为可变长度的有效负载提供空间.然后可以通过例如访问谁的第5个字节.vs->payload[4]
.
这样做的好处是整个对象可以在一次free
调用中释放.并且它保证它在内存中有一个连续的块.因此,它比在堆中的其他位置分配相应的缓冲区更好地利用缓存.
OOP设计模式的程序对应物
OOP模式在程序语言中的名称永远不会被调用.所以我只能猜到这里.
创作模式
if (!initialized) { initialize(); initialized = 1; }
在非性能关键的位置使用该模式.对于性能关键代码,根本不使用延迟加载.用户必须找到初始化上下文的位置.结构模式
行为模式
do
和undo
回调的结构.这些回调通常需要某种上下文来操作.并维护一系列命令以执行撤消.malloc
和free
.《设计模式:可重用面向对象软件的元素》一书是一本具有里程碑意义的书,它将设计模式的注意力带入了计算机编程、设计和体系结构的实践中。当时占主导地位的编程范式是面向对象的软件开发,这本书显然是针对该范式的,而不是其他范式。尽管您可能会认为书中的某些设计模式适用于其他范例,但这不是本书的重点。因此,受到设计师和程序员欢迎的是那本书中概述的一组设计模式。从那时起,其他作者、博主和其他网站都记录了其他内容。毫无疑问,有一些适用于过程语言的设计模式已经在各个网站上进行了描述,但是,正如我所说,当编程社区谈到设计模式时,他们主要指的是那本书中概述的模式。我知道这不是一个真正的答案,因为我不知道过程语言的任何记录模式,我确信肯定有一些模式。我想也许我应该说明那本书的重要性,以及它最初针对的范式。