c - ejemplos - patrones de diseño mas usados
Principios de diseño, mejores prácticas y patrones de diseño para C(o programación procedimental en general)? (5)
¿Existen principios de diseño conocidos, mejores prácticas y patrones de diseño que se puedan seguir al diseñar un proyecto C? ¿O principios de diseño útiles para la programación procedimental (imperativa) en general?
(Soy hijo de la ''generación orientada a objetos'' y tengo que diseñar un gran proyecto C por primera vez)
El estándar de codificación SEI CERT C proporciona un buen conjunto de reglas y buenas prácticas comunes , así como también cosas que debe evitar utilizar.
Hay un buen libro en línea, gratuito, titulado Programación orientada a objetos con ANSI-C , que cubre el tema de escribir código orientado a objetos en C. Una búsqueda en Google de "C orientada a objetos" también produce una serie de otros bienes ejemplos y recursos.
Si su proyecto es crítico para la seguridad, MISRA-C es un buen conjunto de reglas. Está destinado principalmente para c incrustado, pero también puede ser útil en otras áreas.
Me considero un codificador OO, y trabajo mucho con embedded-C. El mejor consejo que puedo dar, especialmente para proyectos grandes, es no exagerar. Crear un marco de OO completo sobre ANSI C puede ser muy tentador, pero se necesita mucho tiempo y esfuerzo para hacerlo bien. Cuanto más entusiasta sea, más tiempo dedicará a depurar su marco en lugar de trabajar en el proyecto real . Acércate a la tarea con la cabeza despejada y una buena y sólida comprensión de YAGNI . ¡La mejor de las suertes!
Mis tres consejos:
- Escribir pruebas unitarias Lo ayudarán a concentrarse en un diseño que resuelva su problema a medida que avanza. Mucho mejor que confiar (únicamente) en el pensamiento premeditado.
- Tener instalado un detector de fugas de memoria (hay todo tipo de bibliotecas) instalado y funcionando desde el primer día. Haga que esta biblioteca imprima todas las filtraciones tan pronto como el programa / pruebas finalice. Esto le permitirá detectar una fuga tan pronto como la presente, haciendo que su fijación sea mucho menos dolorosa.
- Escribir código OOP en C. No es tan difícil. Si bien es posible emular la anulación de métodos, le sugiero que comience con la emulación de objetos simples. Incluso este simple mecanismo puede darte un gran kilometraje.
Aquí hay un ejemplo:
struct Vector {
int size;
int limit;
int* ints;
}
Vector* Vector_new() {
Vector* res = (Vector*) malloc(sizeof(Vector));
res->limit = 10;
res->size = 0;
res->ints = (int*) malloc(sizeof(int) * res.limit);
return res;
}
void Vector_destroy(Vector* v) {
free(v->ints);
free(v);
}
void Vector_add(Vector* v, int n) {
if(v->size == v->limit) {
v->limit = v->limit * 2 + 10;
v->ints = realloc(v->ints, v->limit);
}
v->ints[v->size] = n;
++v->size;
}
int Vector_get(Vector* v, int index) {
if(index >= 0 && index < v->size)
return v->ints[index];
assert false;
}
OOP es una metodología, no una tecnología. Así que mi primer consejo es dejar de pensar en ello como programación de procedimientos.
Para el punto de e.James, no desea intentar y volver a crear un lenguaje orientado a objetos o pretender que tiene las capacidades de los mismos. Todavía puede hacer todo lo correcto al aferrarse a algunos principios simples:
- Prueba de conducir todo.
- Encuentra lo que varía y encapsúlalo.
- Diseño a interfaces.
Ocultamiento de la información: como propuso Parnas ( Fundamentos del software ).
Gestión cuidadosa de encabezados y visibilidad:
- Todo en un archivo fuente que puede ocultarse del mundo exterior debería ser; solo la interfaz externa documentada debe estar expuesta.
- Todo lo que está expuesto se declara en un encabezado.
- Ese encabezado se usa donde se necesita la funcionalidad (y donde se define).
- El encabezado es autónomo: cuando lo necesita, lo usa y no tiene que preocuparse por ''qué otros encabezados también tengo que incluir'' porque el encabezado asegura que funciona al incluir todo lo que necesita para hacerlo trabajo.
El encabezado está autoprotegido, por lo que no importa si se incluye varias veces.
#ifndef HEADER_H_INCLUDED #define HEADER_H_INCLUDED ...rest of header contents, including other #include lines if necessary #endif /* HEADER_H_INCLUDED */
Diseña conjuntos de funciones para trabajar en ''objetos'' (generalmente estructuras) y usa esas funciones en lugar de hurgar en las entrañas de la estructura en el código que la está usando. Piénselo como una encapsulación autoimpuesta.