根据我的经验,我经常会看到一些设计模式,比如访问者模式,策略模式......,像Java这样的面向对象语言......但是我没有在过程语言中看到很多模式,比如C ...我想知道这些模式是否存在于程序语言中?
答案 0 :(得分:26)
程序语言确实有设计模式。但由于程序方法通常被忽略而偏向于基于阶级的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;
在代码中完成以下操作:
VariableSized *vs = malloc(sizeof(VariableSized) + extraLength);
这会分配比结构更大的内存,从而为可变长度的有效负载提供空间。然后可以通过例如访问谁的第5个字节。 vs->payload[4]
。
这样做的好处是可以在一次free
调用中释放整个对象。并且它保证它在内存中有一个连续的块。因此,它比在堆中的其他位置分配相应的缓冲区更好地利用缓存。
OOP设计模式的程序对应
OOP模式在程序语言中的名称永远不会被调用。所以我只能在这里猜测。
创作模式
if (!initialized) { initialize(); initialized = 1; }
模式。对于性能关键代码,根本不使用延迟加载。用户必须找到初始化上下文的位置。 结构模式
行为模式
do
和undo
回调的结构。这些回调通常需要某种上下文来操作。并维护一系列命令以执行撤消。malloc
和free
。答案 1 :(得分:1)
“设计模式:可重复使用的面向对象软件的元素”这本书是一本具有里程碑意义的书,它将设计模式的注意力引入计算机编程,设计和体系结构的实践中。当时占主导地位的编程范式是面向对象的软件开发,这本书明确地针对这种范式,而不是针对其他范例。虽然你可以说本书中的一些设计模式适用于其他范例,但它并不是本书的重点。因此,设计师和程序员最受欢迎的是该书中概述的一组设计模式。从那时起,其他作者,博主和其他网站都记录了其他人。毫无疑问,有些设计模式适用于已在各种网站上描述的过程语言,但是,正如我所说,当编程社区谈到设计模式时,它们大多指的是该书中概述的模式。我知道这不是一个真正的答案,因为我没有任何文档模式用于过程语言,当然有一些,我敢肯定。我想也许我会说明这本书的重要性,以及最初的目标范式。