Are there any "design patterns" in C?
CDesign PatternsC Problem Overview
I know that design patterns is generally something that's connected to OO programming, but do you have some pattern you often use when you program C?
I'm not interested in simple translations of the classical OO patterns and please don't mention Duff's device. ;-)
C Solutions
Solution 1 - C
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.
Solution 2 - C
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.
Solution 3 - C
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.
Solution 4 - C
From the top of my head
Solution 5 - C
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;
}
Solution 6 - C
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.
Solution 7 - C
Virtual File System is perfect example for learning the Design Pattern.