2010-11-06 26 views
53

Sé que los patrones de diseño generalmente son algo que está conectado a la programación de OO, pero ¿tiene algún patrón que a menudo usa cuando programa C?¿Hay algún "patrón de diseño" en C?

No me interesan las traducciones simples de los patrones clásicos de OO y no menciones el dispositivo de Duff. ;-)

Respuesta

56

Mi favorito es el "Patrones en C" serie por Adam Petersen:

También: siempre pienso en goto como la herramienta de un gran pobre para el patrón de decorador.

+7

¿Podría explicarnos qué tiene que ver 'goto' con los decoradores? –

+0

Esta es una gran pequeña serie de Adam Tornhill (fue Petersen). Su [libro completo] (https://leanpub.com/patternsinc) está disponible. Este pequeño conjunto de patrones te llevará un largo camino en C. –

4

Sí, las hay. inicialización perezosa, Singleton, agrupación de objetos, etc. estado del objeto se implementa fácilmente en el más puro C.

Ejemplo (inicialización perezosa)

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

Sí, probablemente lo sean, pero ¿cómo podría implementar uno de estos patrones en C? – onemasse

+0

ejemplo agregado para lazy init – Vlad

+2

El mejor punto es que ** no debe ** implementar malos patrones de diseño (como singletons, también conocidas como variables globales) en C, o en cualquier idioma para ese asunto. –

1

patrones de diseño a menudo modelo cosas que son sólo un nivel de lo que un entorno existente ofertas. Si toma C con su biblioteca estándar como entorno, un patrón de diseño eminente es Orientación de objeto.

4

Polimorfismo mediante devoluciones de llamada, p. Ej. la función de la biblioteca estándar qsort. Todo lo que necesita es una forma de comparar dos elementos, y puede ordenar una matriz de ellos.

Puede ser mucho más sofisticado que esto mediante el uso de conjuntos de funciones (vtables) para representar las propiedades pertinentes de un tipo para que una rutina genérica pueda procesarlo de manera útil. Por ejemplo, las llamadas de lectura, escritura, etc. requieren un archivo abierto o un puerto de red.

+0

Me gusta el uso de devoluciones de llamada. Puede crear una función de desplazamiento de estructura de datos general que ejecute una función de devolución de llamada en cada elemento. – onemasse

7

Los patrones de diseño se pueden ver como características de idioma faltantes. La introducción de Design Patterns: Elements of Reusable Object-Oriented Software afirma:

La elección del lenguaje de programación es importante, ya que influye en su punto de vista . Nuestros patrones asumen Smalltalk/C++ - características de lenguaje de nivel, y esa elección determina qué puede y no se puede implementar fácilmente. Si asumimos los idiomas de procedimiento , podríamos incluir patrones de diseño llamados "Herencia", "Encapsulación", y "Polimorfismo". De manera similar, algunos de los patrones son compatibles directamente con los lenguajes orientados a objetos menos comunes. CLOS tiene métodos múltiples, para el ejemplo , lo que disminuye la necesidad de un patrón , como Visitor. (cursiva es mía)

La frase en cursiva es la respuesta a su pregunta.

0

sistema de archivos virtual es ejemplo perfecto para aprender el patrón de diseño.