JavaRush /Blog Java /Random-ES /Pausa para el café #103. En defensa del “Código Limpio”: ...

Pausa para el café #103. En defensa del “Código Limpio”: 100 consejos atemporales

Publicado en el grupo Random-ES
Fuente: Hackernoon “Clean Code” de Robert C. Martin es el libro de programación más recomendado de todos los tiempos. Busque libros utilizando la consulta "mejores libros para desarrolladores de software" y es casi seguro que encontrará este libro en los resultados de búsqueda. Y aunque algunas personas sienten que no vale la pena prestarle atención al Código Limpio, yo diría que esos sentimientos están profundamente equivocados. Sí, algunos de los consejos del libro son cuestionables. Sí, parte del contenido parece desactualizado. Sí, algunos ejemplos son confusos. Todo es verdad. ¡Pero no nos apresuremos a descartar los muchos consejos útiles que ofrece este libro! Ignorar completamente Clean Code simplemente por algunas malas ideas no es la mejor solución. Pausa para el café #103.  En defensa del “Código Limpio”: 100 consejos eternos - 1Entonces, sin más preámbulos, ¡veamos los mejores consejos que Clean Code tiene para ofrecer! Repasaremos cada capítulo y resumiremos las ideas que ofrecen el tío Bob y sus coautores.

Capítulo 1: Código limpio

  1. La cantidad total de desorden aumenta con el tiempo.

  2. Restaurar un sistema obsoleto desde cero es muy difícil. La refactorización y las mejoras incrementales serán la mejor opción para esto.

  3. En una base de código desordenada, las tareas que sólo deberían llevar unas pocas horas pueden tardar días o semanas en completarse.

  4. Tómese el tiempo para actuar rápidamente.

  5. El código limpio hace una cosa bien. El código incorrecto intenta hacer demasiado.

  6. El código limpio está bien probado.

  7. Al leer código bien escrito, cada función hace más o menos lo que cabría esperar.

  8. Si no estás de acuerdo con un principio enseñado por alguien con años de experiencia, al menos deberías considerar su punto de vista antes de ignorarlo.

  9. El código se lee con mucha más frecuencia de lo que se escribe.

  10. El código que es más fácil de leer es más fácil de cambiar.

  11. Deje el código base mejor que cuando lo encontró (Regla Boy Scout).

Capítulo 2: El significado de los nombres

  1. Elija los nombres de sus variables con cuidado.

  2. Elegir buenos nombres es difícil.

  3. El nombre de una variable o función debe indicar qué es y cómo se utiliza.

  4. Evite el uso de nombres de variables de un solo carácter, excepto los nombres de uso común, como i para una variable de contador en un bucle.

  5. Evite el uso de abreviaturas en los nombres de variables.

  6. Los nombres de las variables deben ser pronunciables para que puedas hablar de ellos y decirlos en voz alta.

  7. Utilice nombres de variables que sean fáciles de encontrar.

  8. Las clases y objetos deben tener nombres en forma de sustantivos.

  9. Los nombres de métodos y funciones deben ser verbos o pares verbo-sustantivo.

Capítulo 3: Funciones

  1. Las funciones deben ser pequeñas.

  2. La función debe realizar una acción.

  3. Las funciones deben tener nombres descriptivos.

  4. Extraiga el código en el cuerpo if/else o cambie las declaraciones a funciones con nombres claros.

  5. Limite el número de argumentos que toma una función.

  6. Si una función requiere muchos argumentos de configuración, considere combinarlos en una única variable de parámetros de configuración.

  7. Las funciones deben ser puras, lo que significa que no tienen efectos secundarios y no modifican sus argumentos de entrada.

  8. La función debe ser un comando o una consulta, pero no ambos a la vez (Command Query Separation).

  9. Es mejor eliminar errores y excepciones del código que dejar errores en el código.

  10. Extraiga código duplicado en funciones con nombres claros (no se repita).

  11. Las pruebas unitarias facilitan la refactorización.

Capítulo 4: Comentarios

  1. Los comentarios pueden ser incorrectos. Es posible que al principio estén equivocados o que inicialmente sean precisos y luego queden obsoletos con el tiempo a medida que cambia el código.

  2. Utilice comentarios para describir por qué está escrito como está, en lugar de explicar lo que está sucediendo.

  3. Los comentarios a menudo se pueden evitar utilizando variables con nombres claros y extrayendo secciones de código en funciones con nombres claros.

  4. Prefije los comentarios TODO con prefijos consistentes para que sean más fáciles de encontrar. Revise y limpie sus comentarios TODO periódicamente.

  5. No utilice Javadocs sólo por utilizarlos. Los comentarios que describen lo que hace un método, qué argumentos toma y qué devuelve son redundantes en el mejor de los casos y engañosos en el peor.

  6. Los comentarios deben incluir toda la información relevante y el contexto que el lector necesitará. No seas perezoso al escribir un comentario.

  7. Los comentarios de registro y los comentarios del autor de archivos no son necesarios debido al control de versiones y la culpa de git.

  8. No comente el código muerto. Simplemente bórralo. Si cree que necesitará el código en el futuro, para eso está el control de versiones.

Capítulo 5: Formateo

  1. Como equipo, seleccione un conjunto de reglas para formatear su código y luego aplique esas reglas de manera consistente. No importa con qué reglas esté de acuerdo, debe llegar a un acuerdo.

  2. Utilice formato de código automático y un analizador de código. No confíe en que las personas encuentren y corrijan manualmente todos los errores de formato. Esto es ineficiente, improductivo y una pérdida de tiempo al revisar el código.

  3. Agregue espacios verticales entre líneas de código para separar visualmente bloques de código relacionados. Todo lo que necesitas es hacer una nueva línea entre los grupos.

  4. Los archivos pequeños son más fáciles de leer, comprender y mover que los archivos grandes.

  5. Las variables deben declararse cerca de donde se utilizan. Para funciones pequeñas, esto suele estar en la parte superior de la función.

  6. Incluso para funciones cortas o declaraciones if, déles formato correctamente en lugar de escribirlas en una línea.

Capítulo 6: Objetos y estructuras de datos

  1. Los detalles de implementación en un objeto deben estar ocultos detrás de la interfaz del objeto. Al proporcionar una interfaz para que la utilicen los consumidores de un objeto, facilita la refactorización posterior de los detalles de implementación sin provocar cambios importantes. Las abstracciones facilitan la refactorización.

  2. Cualquier fragmento de código no debe tener conocimiento de las partes internas del objeto sobre el que opera.

  3. Cuando trabaje con un objeto, debe exigirle que realice un comando o consulta, en lugar de preguntarle sobre sus componentes internos.

Capítulo 7: Corrección de errores

  1. El manejo de errores no debería interferir con el resto del código del módulo.

  2. Es mejor eliminar errores y excepciones del código que dejar errores en el código.

  3. Escriba pruebas con errores para asegurarse de que su código las identifique y no las pase por alto.

  4. Los mensajes de error deben ser informativos, con todo el contexto necesario que alguien pueda necesitar para solucionar el problema de manera efectiva.

  5. Envolver las API de terceros en una fina capa de abstracción hace que sea más fácil reemplazar una biblioteca por otra en el futuro.

  6. Envolver las API de terceros en una fina capa de abstracción hace que sea más fácil burlarse de la biblioteca durante las pruebas.

  7. Utilice el patrón Caso especial o el patrón Objeto nulo para manejar comportamientos excepcionales, como cuando ciertos datos no existen.

Capítulo 8: Límites

  1. Las bibliotecas de terceros ayudan a acelerar la entrega de productos al permitirle subcontratar diversas tareas.

  2. Escriba pruebas para asegurarse de que está utilizando correctamente la biblioteca de terceros.

  3. Utilice el patrón del adaptador para cerrar la brecha entre la API de una biblioteca de terceros y la API que le gustaría tener.

  4. Envolver las API de terceros en una fina capa de abstracción hace que sea más fácil reemplazar una biblioteca por otra en el futuro. (Repetición del Capítulo 7)

  5. Envolver las API de terceros en una fina capa de abstracción hace que sea más fácil burlarse de la biblioteca durante las pruebas. (Repetición del Capítulo 7)

  6. Trate de no brindarle a su aplicación demasiada información sobre los detalles de ninguna biblioteca de terceros.

  7. Es mejor depender de lo que controlas que de lo que no controlas.

Capítulo 9: Pruebas unitarias

  1. El código de prueba debe ser tan limpio como el código de producción (con algunas excepciones, generalmente relacionadas con la memoria o la eficiencia).

  2. A medida que cambia el código de producción, también cambia el código de prueba.

  3. Las pruebas ayudan a mantener su código de producción flexible y mantenible.

  4. Las pruebas le permiten realizar cambios, lo que le permite refactorizar con confianza sin temor a no darse cuenta usted mismo.

  5. Estructura tus pruebas usando el patrón Organizar-Actuar-Afirmar (también conocido como Construir-Operar-Verificar, Configurar-Ejercicio-Verificar o Dado-Cuando-Entonces).

  6. Utilice funciones específicas de dominio para que las pruebas sean más fáciles de escribir y leer.

  7. Califique un concepto por prueba.

  8. Las pruebas deben ser rápidas.

  9. Las pruebas deben ser independientes.

  10. Las pruebas deben ser repetibles.

  11. Las pruebas no deberían requerir confirmación.

  12. Las pruebas deben escribirse de manera oportuna, poco antes o después de escribir el código de producción, no meses después.

  13. Si sus pruebas son malas, espere que haya errores en su código.

Capítulo 10: Clases

  1. Las clases deben ser pequeñas.

  2. Las clases solo deben ser responsables de una cosa y deben tener una sola razón para cambiar (principio de responsabilidad única).

  3. Si no puedes encontrar un nombre claro para la clase, probablemente sea demasiado grande.

  4. Tu trabajo no termina cuando consigues que un fragmento de código funcione. El siguiente paso será refactorizar y limpiar el código.

  5. El uso de muchas clases pequeñas en lugar de varias clases grandes en su aplicación reduce la cantidad de información que un desarrollador debe comprender cuando trabaja en una tarea determinada.

  6. Tener un buen conjunto de pruebas le permite refactorizar con confianza cuando divide clases grandes en otras más pequeñas.

  7. Las clases deben estar abiertas a la extensión, pero cerradas a la modificación (principio de abierto-cerrado).

  8. Las interfaces y las clases abstractas crean uniones que facilitan las pruebas.

Capítulo 11: Sistemas

  1. Utilice la inyección de dependencia para brindar a los desarrolladores la flexibilidad de pasar cualquier objeto con la interfaz adecuada a otra clase.

  2. Utilice la inyección de dependencia para crear interfaces entre objetos en su aplicación para facilitar las pruebas.

  3. Los sistemas de software no son como un edificio que debe diseñarse de antemano. Son más bien ciudades que crecen y se expanden con el tiempo, adaptándose a las necesidades actuales.

  4. Posponer la toma de una decisión hasta el último momento crítico.

  5. Utilice un lenguaje específico del dominio para que los expertos y desarrolladores del dominio utilicen la misma terminología.

  6. No complique demasiado su sistema. Utilice lo más simple que funcione.

Capítulo 12: Implementación

  1. Los sistemas que no se pueden probar no se pueden verificar y los sistemas que no se pueden verificar nunca deben implementarse.

  2. Escribir pruebas conduce a un mejor diseño porque el código que es fácil de probar a menudo utiliza inyección de dependencia, interfaces y abstracción.

  3. Un buen conjunto de pruebas eliminará el temor de dañar su aplicación mientras la refactoriza.

  4. Duplicar código crea más riesgo porque hay más lugares en el código que se pueden cambiar e incluso más lugares donde se pueden ocultar errores.

  5. El código que escribe ahora es más fácil de entender porque está profundamente involucrado en comprenderlo. No es fácil para otros alcanzar rápidamente el mismo nivel de comprensión.

  6. La mayor parte del costo de un proyecto de software está relacionado con el mantenimiento a largo plazo.

  7. Las pruebas sirven como documentación viva de cómo debe comportarse (y se comporta) su aplicación.

  8. No avance más una vez que su código funcione. Tómese el tiempo para hacerlo más claro y comprensible.

  9. Lo más probable es que la próxima persona que lea su código en un futuro próximo sea usted. Sea amable con su yo futuro escribiendo código que sea fácil de entender.

  10. Resista el dogma. Adopte el pragmatismo.

  11. Se necesitan décadas para convertirse en un ingeniero de software realmente bueno. Puede acelerar su curva de aprendizaje aprendiendo de los expertos que lo rodean y aprendiendo patrones de diseño de uso común.

Capítulo 13: Paralelismo

  1. Escribir código paralelo es difícil.

  2. Los errores y problemas ocasionales que son difíciles de reproducir suelen ser problemas de concurrencia.

  3. Las pruebas no garantizan que su aplicación esté libre de errores, pero minimizarán el riesgo.

  4. Conozca los problemas comunes de concurrencia y sus posibles soluciones.

Capítulo 14: Refinamiento secuencial

  1. El código limpio no suele empezar con una pizarra en blanco. Primero escribe una solución aproximada y luego la refactoriza para hacerla más limpia.

  2. Es un error dejar de trabajar en el código una vez que ha empezado a funcionar. Tómese el tiempo para mejorarlo aún más después de que ya esté funcionando.

  3. Los disturbios crecen gradualmente.

  4. Si se encuentra en un aprieto en el que agregar funciones es demasiado difícil o lleva demasiado tiempo, deje de escribir funciones y comience a refactorizar.

  5. El cambio incremental suele ser mejor que reconstruir desde cero.

  6. Utilice el desarrollo basado en pruebas (TDD) para realizar una gran cantidad de cambios muy pequeños.

  7. Un buen diseño de software implica separar las preocupaciones de su código y separar el código en módulos, clases y archivos más pequeños.

  8. Es más fácil limpiar un desastre inmediatamente después de haberlo hecho que limpiarlo más tarde.

Capítulo 15: Partes internas de JUnit

  1. Los nombres de variables negativos o las expresiones condicionales son un poco más difíciles de entender que los positivos.

  2. La refactorización es un proceso iterativo lleno de prueba y error.

  3. Deje el código base mejor que cuando lo encontró (Regla Boy Scout). (Repetido del Capítulo 1)

Capítulo 16: Refactorización de SerialDate

  1. Las revisiones de código y las críticas a nuestro código nos hacen mejores, y eso deberíamos agradecerlo.

  2. Primero haga que el código funcione y luego corríjalo.

  3. No es necesario probar todas las líneas de código.

Capítulo 17: Olores y heurísticas

  1. El código limpio no es un conjunto de reglas, sino un sistema de valores que determinan la calidad de tu trabajo.

[En este capítulo, el tío Bob enumera 66 variaciones más de su código y heurística, muchas de las cuales se tratan en el resto del libro. Reproducirlos aquí sería esencialmente copiar y pegar el nombre de cada elemento, por lo que me abstuve de hacerlo. ¡Te sugiero que leas el libro!]

Conclusión

Terminemos donde empezamos: Clean Code de Robert C. Martin es el libro de programación más recomendado de todos los tiempos. Hay una buena razón para esto.
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION