C中是否有任何“设计模式”?[关闭]


81

我知道设计模式通常与OO编程相关,但是您在编程C时是否经常使用某些模式?

我对经典OO模式的简单翻译不感兴趣,请不要提及Duff的设备。;-)

Answers:


83

我最喜欢的是亚当·托恩希尔Adam Tornhill)的“ C模式”系列:

另外:我一直认为goto这是装饰图案的可怜人的工具。

更新:我强烈建议使用Rustrust-lang.org)而不是C,除非您需要使用c。Rust具有c的所有优点,包括速度和与c的二进制库兼容性,但是编译器处理了许多复杂性,以确保代码是内存安全的并且不包含数据竞争。它也是便携式的,具有用于执行常见任务的标准库,并且对于各种设计模式更容易编程。


9
您能否详细说明goto与装饰器有什么关系?
GuiPrá15年

这是亚当·托恩希尔(Adam Tornhill)(彼得森(Petersen))创作的精彩小系列。他的完整书可供选择。这个小组模式将带你很长的路要走C.
克林特Pachl

10

设计模式可以视为缺少语言功能。设计模式简介:可重用的面向对象软件的元素指出:

编程语言的选择很重要,因为它会影响一个人的观点。我们的模式假定使用Smalltalk / C ++级别的语言功能,并且该选择确定了可以轻松实现的内容。如果我们采用过程语言,则可能包括称为“继承”,“封装”和“多态”的设计模式。同样,不太常见的面向对象语言直接支持我们的某些模式。例如,CLOS具有多种方法,可以减少对访问者之类的模式的需求。(斜体

斜体字是您问题的答案。


7

通过回调的多态性,例如标准库的qsort功能。它所需要的只是一种比较两个元素的方法,并且可以对它们进行排序。

通过使用函数集(vtables)表示类型的相关属性,您可以比这复杂得多,以便泛型例程可以对其进行有用的处理。例如,在打开的文件或网络端口上的读取,写入等调用。


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

5

是的,有。延迟初始化,单例,对象池,对象状态等都可以在纯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 2010年

2
更好的一点是,您不应该在C或与此相关的任何语言中实现不良的设计模式(例如单例,aka全局变量)。
R .. GitHub停止帮助ICE,2010年

4
@R .:我真的不认为单例本身就是一个坏模式。在某些情况下,它可能是有用和高效的,在某些情况下,可能对代码质量有害。但是开发人员必须了解设计模式的优缺点,并明智地使用它们。
弗拉德(Flad)2010年


2

设计模式通常对事物进行建模,而这些事物与现有环境所提供的只是一个层次。如果您将C及其标准库用作环境,那么杰出的设计模式就是“对象定向”。


2

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.