Últimamente algo ando espeso, lo siento. Tengo la cabeza tan llena de cosas del trabajo que no me da tiempo a escribir nada bueno para el blog, ni a pensar en nuevos temas ni nada. Disculpen si esto baja un poco el ritmo de actualización. Y de originalidad.
Como saben ustedes (y si no lo saben se lo cuento), yo soy programador. Programador de C, para ser más exacto. Ahórrense las condolencias: me gusta mi trabajo. Programo sistemas empotrados, que es como ordenadores, pero más pequeños y desnudos. Todo una delicia, si no atendemos al componente sexual del asunto.
La cuestión es que hace unos meses encontré este vetusto texto de Internet: How to write unmanteinable code, y me pegué una jartá a reír. Comento, para quien no lo sepa, que el código con el que funcionan los programas difícilmente es escrito por una sola persona y, en cualquier caso, es muy fácil que otra tenga que leerlo y entenderlo para actualizarlo, añadir funcionalidades y quitar otras. A eso se le llama mantener una aplicación. El problema que tenemos es que, por lo general, cada uno tiene un estilo a la hora de programar y entender un programa que ha escrito otro puede ser tremendamente complicado.
Para conseguir código mantenible existen centenares de guías. Y normas. Pero sólo existe una para escribir código inmantenible. Les traduzco algunas de las recomendaciones más graciosas que he encontrado en ella1.
[Advertencia]: si usted no es informático, el concepto que tenemos usted y yo de lo que es gracioso y lo que no lo es puede variar mucho.
Nombrado de variables
Si llamas a tus variables a, b, c, entonces será imposible encontrarlas usando un buscador común. Además, nadie tendrá ni idea de para qué sirven. Anima a los lectores de tu programa a encontrar cada ocurrencia leyendo todas la lineas de todos los ficheros: así entenderán mejor el programa.
A.C.R.O.N.Y.M.S.: utiliza acrónimos para mantener el código carente de emoción. Los hombres de verdad jamás explican los acrónimos: los entienden por genética.
Reusa nombres: nunca está de más ser ecológicos. Siempre que el lenguaje lo permita, llama a funciones, variables y parámetros con los mismo nombres. El objetivo es obligar al mantenedor a que conozca perfectamente las reglas de ámbito del lenguaje.
Elige nombres con connotaciones emocionales irrelevantes y opera con ellos, p.ej.
marypoppins = (superman + starship) / god;
Esto confundirá al lector, que suele asociar nombres de variable de algún modo con el valor que contiene.
Asegúrate de que cada función realiza un poco más (o menos) de lo que su nombre indica. Como simple ejemplo, un método llamado isValid(x) puede tener como efecto colateral convertir x a binario y almacenarlo en una base de datos.
Emplea referencias ocultas a películas. Usa nombres constantes como LancelotsFavouriteColour en vez de azul y asígnalo al valor hexadecimal de 0x0204FB. El color es idéntico al azul de la pantalla y el programador mantenedor tendrá que buscar alguna herramienta gráfica para asaber qué color es. Sólo alguien muy familiar con los Monty Python (y los caballeros de la mesa cuadrada) sabrá que el color favorito de Lancelot era el azul. Si el programador mantenedor no puede citar de memoria las películas enteras de los Monty Python, entonces no tiene futuro como programador.
Camuflaje
Incluye secciones de código que están comentadas pero que a primera vista no lo estén. Por ejemplo:
for(j=0; j < array_len; j+ =8)
{
total += array[j+0 ];
total += array[j+1 ];
total += array[j+2 ]; /* Main body of
total += array[j+3]; * loop is unrolled
total += array[j+4]; * for greater speed.
total += array[j+5]; */
total += array[j+6 ];
total += array[j+7 ];
}
Recuerda al mantenedor las reglas de asociación añadiendo instrucciones que resultan ser comentarios.
Importantvalue = a/*p /* divide by the value pointed */;
Si tienes suerte y el compilador permite comentarios anidados, puedes reservar muchas sorpresas hasta que se descubra que no existe división alguna.
Esconde las definiciones de las macros, entre comentarios inútiles. Así el programador se aburrirá y no llegará a descubrirla. Asegúrate de que la macro reemplaza una asignación perfectamente normal por cualquier operación rara, por ejemplo:
#define a=b a=0-b
Aunque ya tengas una variable llamada xy_z, no hay ninguna razón para que no puedas emplear también otras con nombres similares, como xy_Z, xy__z, _xy_z, _xyz, XY_Z, xY_z, and Xy_z. Sé creativo: variables que se distinguen tan sólo por las mayúsculas y barras bajas tienen la ventaja de confundir a quienes recuerdan los nombres por cómo suenan, en vez de por su representación exacta.
Elige el mejor operador de sobrecarga: En C++, sobrecarga los operadores +,-,*,/ para hacer cosas totalmente diferentes de suma, resta... Después de todo, si Stroustroup puede usar el operador de desplazamiento para entrada/salida, ¿por qué no ser igual de creativo?. Si sobrecargas +, asegúrate de que i = i + 5 tiene un significado completamente distinto a i += 5.
Documentación
Miente en los comentarios. Es muy sencillo: no actualices los comentarios al actualizar el código.
Documenta cómo y no el porqué. Documenta sólo los detalles de lo que el programa hace (incluyendo los autoincrementos), no lo que pretende conseguir. Así, si hay algún error, el que lo tenga que arreglar no tendrá pistas para sabe qué es lo que el código debería estar haciendo.
Nunca documentes errores en el código. Si sospechas que hay un bug, mantenlo en secreto. Si crees que el código puede ser mejorado o reorganizado, por el amor de Dios, no lo digas. Recuerda las palabras en la película Bambi: Si no puede decir nada bonito, mejor no digas nada. Qué sucederá si el que lo escribió ve tu comentario?. ¿Y un cliente?. ¡Podrías estar despedido!. En cambio, un comentario del tipo: /* This needs to be fixed! */ puede hacer maravillas, sobretodo si no se sabe a qué se refiere. De este modo nadie podrá ser criticado.
Diseño
Gasta arrays de tres dimensiones: montones de ellos. Mueve datos entre ellos de originales maneras, llenando las columnas de uno con las filas de otro. Si el desplazamiento es de uno, sin razón aparente, bien hecho. Hace que el mantenedor se ponga nervioso.
Utiliza todas la variables globales que puedas. Si Dios no hubiera querido que usáramos variables globales, no las habría inventado. Cada función debe usar y dar valor a un par de variables globales al menos, incluso aunque no exista ninguna buena razón para ello. Al fin y al cabo, el mantenedor se figurará que es una especie de detective y estará contento de cumplir una tarea que separa a los verdaderos programadores de los aficionadillos.
Testing
Que tu proyecto sólo funcione en modo debug. Si tienes distintas configuraciones de proyecto, asegúrate de que tan sólo funciona con una de ellas. Es muy sencillo de realizar con directivas de preproceso: #define TESTING te da la oportunidad de tener dos secciones del código independientes. Dentro de #ifdef TESTING asigna los valores necesarios para que funcione el programa. Si alguien elimina el define, o mejor aún, no compila con la directiva adecuada, el programa no funcionará.
Testear es de cobardes. Un programador valiente se saltará este paso. Demasiados programadores temen perder su empleo y tienen miedo del jefe y del cliente. Este miedo les paraliza y reduce su productividad. Estudios han demostrado que eliminando las fases de test se puede adelantar las fechas de entrega, algo positivo para el proceso. Sin el miedo, las innovación y experimentación pueden florecer. El trabajo del programador es producir código, y mantenerlo es tarea de otros.
(...)
En fin, la lista tiene años y tiene multitud de ideas gloriosas para escribir código inmantenible. Si tiene tiempo y es usted programador de Java, C o C++ échele un vistazo. Si quiere escribir bien, en cambio, lo tiene más complicado.
Posts relacionados