C语言中是否存在“设计模式”?

103

我知道设计模式通常与面向对象编程有关,但是你是否在使用C编程时经常使用一些模式?

我对古典的面向对象模式的简单翻译不感兴趣,请不要提到Duff设备。;-)

7个回答

103

我最喜欢的是Adam Tornhill的"C语言设计模式"系列:

此外:我总是认为goto是装饰器模式中一个很好的穷人工具。

更新:我强烈建议使用Rustrust-lang.org)或Zigziglang.org),除非需要使用 C。 Rust 具有 C 的所有优点,包括速度和与 C 的二进制库兼容性,但编译器处理大部分复杂性以确保代码是内存安全的且不包含数据竞争。它还具有可移植性,为常见任务提供标准库,并且更容易实现各种设计模式。


12
goto与装饰器有什么关系,您能详细说明一下吗? - Gui Prá
2
这是Adam Tornhill(曾用名Petersen)的一系列精彩小册子。他的完整书籍已经发布。这些少量的模式将在C语言中帮助您走得更远。 - Clint Pachl
2
Rust并不完全等同于C。它足够不同,不能等同对待。例如,您可以从几乎任何编程语言调用C代码,但在Rust中必须关闭名称混淆。此外,Rust通过借用检查器防止保留理论保证的有效程序。我也喜欢Rust,但认为这个观点值得反驳。 - Bots Fab
@BotsFab 好的,我已经添加了Zig。 :) - coolaj86

14
设计模式可以被视为缺失的语言特性。可复用面向对象软件的设计模式的介绍部分指出:
选择编程语言很重要,因为它会影响一个人的观点。我们的模式假定Smalltalk/C++级别的语言特性,而这个选择决定了什么可以轻松实现和不能轻松实现。如果我们假设过程化语言,我们可能已经包含了名为"Inheritance"、"Encapsulation"和"Polymorphism"的设计模式。同样,一些我们的模式直接由不常见的面向对象语言支持。例如,CLOS有多方法,这减少了像Visitor这样的模式的需要。(斜体是我的
斜体字句子就是你问题的答案。

9

通过回调实现多态,例如标准库的qsort函数。它只需要一种比较两个元素的方式,就可以对数组进行排序。

您可以使用函数集合(vtables)来表示类型的相关属性,以便通用程序可以有用地处理它。例如,对打开的文件或网络端口进行读取、写入等调用。


我喜欢使用回调函数。您可以创建一个通用的数据结构遍历函数,对每个元素执行回调函数。 - onemasse


6
是的,有。懒加载、单例模式、对象池、对象状态等都可以在纯C中轻松实现。
示例(懒加载):
#include <stdio.h>

struct foo
{
    int payload;
};

int calculate_payload()
{
    printf("%s\n", "Performing lengthy initialization...");
    return 42;
}

struct foo *get_default_foo()
{
    static int foo_calculated = 0;
    static struct foo default_foo;
    if (!foo_calculated) /* assuming single-threaded access */
    {
        foo_calculated = 1;
        default_foo.payload = calculate_payload();
    }
    return &default_foo;
}

int main()
{
    struct foo *foo1, *foo2;

    printf("%s\n", "Starting the program");

    foo1 = get_default_foo();
    printf("%d\n", foo1->payload);

    foo2 = get_default_foo();
    printf("%d\n", foo2->payload);

    return 0;
}

是的,它们可能是,但是你通常如何在C语言中实现这些模式? - onemasse
2
更好的做法是,不应该在 C 或任何语言中实现糟糕的设计模式(比如单例模式,也称为全局变量)。 - R.. GitHub STOP HELPING ICE
4
@R.: 我真的不认为单例模式本身是一种坏模式。在某些情况下,它可以是有用且高效的,在某些情况下会对代码质量产生负面影响。但是开发者必须知道设计模式的优缺点,并明智地使用它们。 - Vlad

3

设计模式通常模拟的是距离现有环境仅一级的事物。如果您以C语言及其标准库作为环境,那么杰出的设计模式就是面向对象编程。


3

虚拟文件系统是学习设计模式的完美示例。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接