Bill Sourour tiene una excelente publicación en Medium sobre el código del que está avergonzado desde un punto de vista ético. Pero también hay muchas razones técnicas para avergonzarse de su software. Aquí te presento los 11 adjetivos que describen software del que no se avergonzarían.
No importa qué lenguaje o tecnología utilices, si puedes describir tu código con estos adjetivos, el resto probablemente siga. Mira cuántos puedes aplicar a tu propio código.
1. Depurable
La mayoría de los runtimes modernos te permiten conectar un depurador de algún tipo. Incluso Node.js se puede depurar con Visual Studio. Deberías escribir tu código con la idea de que algún día podrías adjuntar un depurador para descubrir qué demonios está sucediendo.
Es difícil describir lo que eso significa exactamente, pero cuando lo haces, afecta cómo estructurar los datos a veces. Puede usar más variables temporales para que no tenga que excavar a través de una estructura. Afortunadamente, la mayoría de esto resulta ser una buena práctica de todos modos.
La mejor manera de comenzar es practicar el uso de un depurador cuando no tenga un problema. Paso a paso y ver cómo se desenvuelve una tarea o instrucción: ¿qué harías si tuviera el valor equivocado?…uhm
2. Registrable
Incluso si tiene un depurador moderno que puedes adjuntar a tu tiempo de ejecución (runtime) y pasar a través de tu código, el mundo simplemente no funciona de esa manera. Es decir, tu código puede ejecutarse en otro lugar, puede ser sin servidor, puede ser multiproceso o distribuido, o puede ejecutarse en una nube en alguna parte. En esos entornos, puede que no se comporte igual que en tu computadora.
Entonces, vas a necesitar un registro. Y eso significa que necesita un marco de registro (logging framework). Debes escribir el código y configurar el registro de forma que el registro sea legible o al menos digerible con algún tipo de lector de registro.
En general, el registro es ciertamente una práctica fundamental que proporciona beneficios significativos durante la vida útil de una aplicación. Algunas herramientas, como Loggly, Logstash, Graylog, etc., te ayudan a analizar y supervisar los registros.
3. Comprobable
En fin, escribe pruebas unitarias. Las pruebas unitarias son un factor importante en la creación de código de calidad.
El software comprobable/testable se divide en funciones inteligibles que hacen cosas simples verificables. El software comprobable funciona mejor y es más flexible.
Si tienes un código viejo que no tiene pruebas, escribe pruebas mientras modifica ese código. ¡Escríbelos primero si puedes! Si tienes que reestructurar algo para que sea comprobable, hazlo (poco a poco, pero hazlo).
4. Fracasable rápidamente
La señal de advertencia más grande para el código no confiable es una línea de código similar a:
if (mivariable == null) mivariable ="";
El desarrollador que escribió esta línea te llevó por un camino hacia un comportamiento intermitente. El comportamiento intermitente te deja en suspenso hasta ese momento especial cuando todo explota en tu cara.
Si algo “no puede suceder”, entonces no debería suceder. Cuando lo haga, el código debería salir con un gran mensaje de error. Es feo, pero significa que el problema se solucionará y no causará más problemas.
5. Idempotente
Esa palabra extraña que significa “si vuelves a hacer esto no importará“. Si bien no todo puede ser idempotente, cualquier cosa que pueda ser, debería ser. Es decir, si actualizas una página de comercio, no debe terminar con dos pedidos (simplemente porque hay un token de la página anterior que se verificó y en su lugar se le asigna un estado de pedido).
El comportamiento idempotente debe impregnar el código. Esto significa que cuando cambias una línea en el depurador y ves si eso soluciona el problema para que el depurador vuelva al principio de la rutina, todo saldrá bien. Esto lo convierte en un software predecible que no crea problemas de datos fácilmente.
6. Inmutable
El código funcional ha hecho que esto sea un hecho. Cuando tiene una variable, se le asigna una vez y luego cambia el resultado en una nueva estructura de datos. Incluso si no estás escribiendo un código funcional, puedes lograr la inmutabilidad.
El código inmutable es más resistente y evita todo tipo de desorden en los hilos. Hay razones de bajo nivel (número de envíos) que pueden hacer que el código inmutable (u funcional u orientado a objetos) no sea deseable para casos especiales (como escribir un intérprete de bajo nivel), pero esas razones no existen en el código de negocios normal que la mayoría de ustedes están escribiendo. (Esto significa que ninguna optimización de los envíos está a la altura de tu primera llamada de E/S.)
7. Inteligible
Cuando la programación funcional se puso de moda, la gente se volvió un poco loca y olvidó que el código aún necesita ser legible. Lo mismo ocurre con el código orientado a objetos una o dos década antes.
Como primer principio, la compilación crea un código que la computadora puede leer. Tu trabajo como desarrollador es hacer código que una persona pueda leer.
8. Modificable
No hace mucho tiempo, quería hacer un cambio super simple a un fragmento de código (tomar el nombre de usuario del contexto de la sesión). Debido a la forma en que se escribió este código, hubo mucho por desenredar y modificar para obtenerlo y llevarlo al lugar que se necesitaba. En otras palabras, el código no era modificable, excepto por el tipo que lo escribió. Cualquiera que sea el principio de diseño que estaba usando no fue documentado, inteligible ni fácil de entender por el siguiente desarrollador en el futuro.
Cada clase, módulo, función, etc. debe escribirse con la idea de que las cosas pueden cambiar. Es posible que necesite una pieza más de datos (como información de seguridad o contexto). Casi siempre hay una versión 2 de cualquier cosa, así que escribe tu código con la idea de que esto sucederá.
En el código orientado a objetos, eso significa no crear una estructura de herencia masiva. En la programación funcional, puede significar el diseño de funciones que no son tan finas o con parámetros que tienen contexto.
9. Documentable
Un buen código debería auto-editarse en gran medida. Esto es acerca de la clase, la función y el nombramiento de variables. También se trata de JavaDoc (o el equivalente de tu lenguaje). También se trata del diseño del código.
Si no puedes documentar “esta cosa” y “lo que hace” sin referirse a otras diez cosas, tal vez deberías reconsiderar el diseño.
10. Modular
Un buen código se divide en partes lógicas que se pueden ejecutar y modificar de forma independiente.
11. Edificable
Si otros desarrolladores no pueden simplemente tomar tu código de Git y ejecutar la compilación, debes trabajar en esa compilación. (Sí, está bien si necesitan una herramienta de compilación “conocida” como Maven). Si requiere un proceso de construcción de una semana, varios días o varias horas, entonces tu construcción necesita trabajo.
Nada grava más a un equipo que una construcción que debe ser combatida por cada nuevo miembro del equipo, cuando los desarrolladores consiguen nuevos equipos, durante una versión importante o durante un lanzamiento importante.