C 语言中有没有“设计模式”?

我知道设计模式通常与面向对象编程相关,但是您在编写 C 程序时经常使用某些模式吗?

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

71458 次浏览

Yes, there are. Lazy initialization, singleton, object pool, object state etc. are easily implemented in pure C.

Example (lazy initialization)

#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;
}

Design Patterns often model things that are just one level from what an existing environment offers. If you take C with its standard library as the environment an eminent design pattern is Object Orientation.

Polymorphism via callbacks, e.g. the standard library's qsort function. All it needs is a way to compare two elements, and it can sort an array of them.

You can be much more sophisticated than this by using sets of functions (vtables) to represent the pertinent properties of a type so that a generic routine can process it usefully. For example, the read, write, etc. calls on an open file, or network port.

Design Patterns could be viewed as missing language features. The Introduction of Design Patterns: Elements of Reusable Object-Oriented Software states:

The choice of programming language is important because it influences one's point of view. Our patterns assume Smalltalk/C++-level language features, and that choice determines what can and cannot be implemented easily. If we assumed procedural languages, we might have included design patterns called "Inheritance," "Encapsulation," and "Polymorphism." Similarly, some of our patterns are supported directly by the less common object-oriented languages. CLOS has multi-methods, for example, which lessen the need for a pattern such as Visitor. (italics mine)

The sentence in italics is the answer to your question.

Virtual File System is perfect example for learning the Design Pattern.

My favorite is the "Patterns in C" series by Adam Tornhill:

Also: I always think of goto as a great poor man's tool for the decorator pattern.

Update: I'd highly recommend using Rust (rust-lang.org) rather than C except where you are required to use c. Rust has all of the benefits of c, including speed and binary library compatibility with c, but the compiler handles much of the complexity to ensure that the code is memory safe and does not contain data races. It's also portable, has a standard library for common tasks, and much easier to program with for various design patterns.