Código Limpio
Autor/a : Robert C. Martin
Cada año, se invierten innumerables horas y se pierden numerosos recursos debido a código mal escrito, ralentizando el desarrollo, disminuyendo la productividad, generando graves fallos e incluso pudiendo acabar con la organización o empresa.
Índice
Prólogo Introducción Sobre la imagen de cubierta 1. Código limpio Hágase el código Código incorrecto El coste total de un desastre El gran cambio de diseño Actitud - El enigma ¿El arte del código limpio? Concepto de código limpio Escuelas de pensamiento Somos autores La regla del Boy Scout Precuela y principios Conclusión Bibliografía 2. Nombres con sentido Introducción Usar nombres que revelen las intenciones Evitar la desinformación Realizar distinciones con sentido Usar nombres que se puedan pronunciar Usar nombres que se puedan buscar Evitar codificaciones - Notación húngara - Prefijos de miembros - Interfaces e implementaciones Evitar asignaciones mentales Nombres de clases Nombres de métodos No se exceda con el atractivo Una palabra por concepto No haga juegos de palabras Usar nombres de dominios de soluciones Usar nombres de dominios de problemas Añadir contexto con sentido No añadir contextos innecesarios Conclusión 3. Funciones Tamaño reducido - Bloques y sangrado Hacer una cosa - Secciones en funciones Un nivel de abstracción por función - Leer código de arriba a abajo: la regla descendente Instrucciones Switch Usar nombres descriptivos Argumentos de funciones - Formas monádicas habituales - Argumentos de indicador - Funciones diádicas - Triadas - Objeto de argumento - Listas de argumentos - Verbos y palabras clave Sin efectos secundarios - Argumentos de salida Separación de consultas de comando Mejor excepciones que devolver códigos de error - Extraer bloques Try/Catch - El procesamiento de errores es una cosa - El imán de dependencias Error.java No repetirse Programación estructurada Cómo crear este tipo de funciones Conclusión SetupTeardownIncluder Bibliografía 4. Comentarios Los comentarios no compensan el código incorrecto - Explicarse en el código Comentarios de calidad - Comentarios legales - Comentarios informativos - Explicar la intención - Clarificación - Advertir de las consecuencias - Comentarios TODO - Amplificación - Javadoc en API públicas Comentarios incorrectos - Balbucear - Comentarios redundantes - Comentarios confusos - Comentarios obligatorios - Comentarios periódicos - Comentarios sobrantes - Comentarios sobrantes espeluznantes - No usar comentarios si se puede usar una función o una variable - Marcadores de posición - Comentarios de llave de cierre - Asignaciones y menciones - Código comentado - Comentarios HTML - Información no local - Demasiada información - Conexiones no evidentes - Encabezados de función - Javadocs en código no público - Ejemplo Bibliografía 5. Formato La función del formato Formato vertical - La metáfora del periódico - Apertura vertical entre conceptos - Densidad vertical - Distancia vertical - Declaraciones de variables - Variables de instancia - Funciones dependientes - Afinidad conceptual - Orden vertical Formato horizontal - Apertura y densidad horizontal - Alineación horizontal - Sangrado - Romper el sangrado - Ámbitos ficticios - Reglas de equipo - Reglas de formato de Uncle Bob 6. Objetos y estructuras de datos Abstracción de datos Antisimetría de datos y objetos La ley de Demeter - Choque de trenes - Híbridos - Ocultar la estructura Objetos de transferencia de datos - Registro activo Conclusión Bibliografía 7. Procesar errores Usar excepciones en lugar de códigos devueltos Crear primero la instrucción try-catch-finally Usar excepciones sin comprobar Ofrecer contexto junto a las excepciones Definir clases de excepción de acuerdo a las necesidades del invocador Definir el flujo normal No devolver Null No pasar Null Conclusión Bibliografía 8. Límites Utilizar código de terceros Explorar y aprender límites Aprender log4j Las pruebas de aprendizaje son algo más que gratuitas Usar código que todavía no existe Límites limpios Bibliografía 9. Pruebas de unidad Las tres leyes del DGP Realizar pruebas limpias - Las pruebas propician posibilidades Pruebas limpias - Lenguaje de pruebas específico del dominio - Un estándar dual Una afirmación por prueba - Un solo concepto por prueba F.I.R.S.T. Conclusión Bibliografía 10. Clases Organización de clases - Encapsulación Las clases deben ser de tamaño reducido - El Principio de responsabilidad única - Cohesión - Mantener resultados consistentes en muchas clases de tamaño reducido Organizar los cambios - Aislarnos de los cambios Bibliografía 11. Sistemas Cómo construir una ciudad Separar la construcción de un sistema de su uso - Separar Main - Factorías - Inyectar dependencias Evolucionar - Aspectos transversales Proxies de Java Estructuras AOP Java puras - Aspectos de AspectJ Pruebas de unidad de la arquitectura del sistema Optimizar la toma de decisiones Usar estándares cuando añadan un valor demostrable Los sistemas necesitan lenguajes específicos del dominio Conclusión Bibliografía 12. Emergencia Limpieza a través de diseños emergentes Primera regla del diseño sencillo: Ejecutar todas las pruebas Reglas 2 a 4 del diseño sencillo: Refactorizar Eliminar duplicados Expresividad Clases y métodos mínimos Conclusión Bibliografía 13. Concurrencia ¿Por qué concurrencia? - Mitos e imprecisiones Desafíos Principios de defensa de la concurrencia - Principio de responsabilidad única (SRP) - Corolario: Limitar el ámbito de los datos - Corolario: Usar copias de datos - Corolario: Los procesos deben ser independientes Conocer las bibliotecas - Colecciones compatibles con procesos Conocer los modelos de ejecución - Productor-Consumidor - Lectores-Escritores - La cena de los filosofos Dependencias entre métodos sincronizados Reducir el tamaño de las secciones sincronizadas Crear código de cierre correcto es complicado Probar código con procesos - Considerar los fallos como posibles problemas de los procesos - Conseguir que primero funcione el código sin procesos - El código con procesos se debe poder conectar a otros elementos - El código con procesos debe ser modificable - Ejecutar con más procesos que procesadores - Ejecutar en diferentes plataformas - Diseñar el código para probar y forzar fallos - Manual - Automática Conclusión Bibliografía 14. Refinamiento sucesivo Implementación de Args - Cómo se ha realizado Args: El primer borrador - Entonces me detuve - Sobre el incrementalismo Argumentos de cadena Conclusión 15. Aspectos internos de JUnit La estructura JUnit Conclusión 16. Refactorización de SerialDate Primero, conseguir que funcione Hacer que sea correcta Conclusión Bibliografía 17. Síntomas y heurística Comentarios - C1: Información inapropiada - C2: Comentario obsoleto - C3: Comentario redundante - C4: Comentario mal escrito - C5: Código comentado Entorno - E1: La generación requiere más de un paso - E2: Las pruebas requieren más de un paso Funciones - F1: Demasiados argumentos - F2: Argumentos de salida - F3: Argumentos de indicador - F4: Función muerta General - G1: Varios lenguajes en un archivo de código - G2: Comportamiento evidente no implementado - G3: Comportamiento incorrecto en los límites - G4: Medidas de seguridad canceladas - G5: Duplicación - G6: Código en un nivel de abstracción incorrecto - G7: Clases base que dependen de sus variantes - G8: Exceso de información - G9: Código muerto - G10: Separación vertical - G11: Incoherencia - G12: Desorden - G13: Conexiones artificiales - G14: Envidia de las características - G15: Argumentos de selector - G16: Intención desconocida - G17: Responsabilidad desubicada - G18: Elementos estáticos incorrectos - G19: Usar variables explicativas - G20: Los nombres de función deben indicar lo que hacen - G21: Comprender el algoritmo - G22: Convertir dependencias lógicas en físicas - G23: Polimorfismo antes que If/Else o Switch/Case - G24: Seguir las convenciones estándar - G25: Sustituir números mágicos por constantes con nombre - G26: Precisión - G27: Estructura sobre convención - G28: Encapsular condicionales - G29: Evitar condicionales negativas - G30: Las funciones solo deben hacer una cosa - G31: Conexiones temporales ocultas - G32: Evitar la arbitrariedad - G33: Encapsular condiciones de límite - G34: Las funciones solo deben descender un nivel de abstracción - G35: Mantener los datos configurables en los niveles superiores - G36: Evitar desplazamientos transitivos Java - J1: Evitar extensas listas de importación mediante el uso de comodines - J2: No heredar constantes - J3: Constantes frente a enumeraciones Nombres - N1: Elegir nombres descriptivos - N2: Elegir nombres en el nivel correcto de abstracción - N3: Usar nomenclatura estándar siempre que sea posible - N4: Nombres inequívocos - N5: Usar nombres extensos para ámbitos extensos - N6: Evitar codificaciones - N7: Los nombres deben describir efectos secundarios Pruebas (Test) - T1: Pruebas insuficientes - T2: Usar una herramienta de cobertura - T3: No ignorar pruebas triviales - T4: Una prueba ignorada es una pregunta sobre una ambigüedad - T5: Probar condiciones de límite - T6: Probar de forma exhaustiva junto a los errores - T7: Los patrones de fallo son reveladores - T8: Los patrones de cobertura de pruebas pueden ser reveladores - T9: Las pruebas deben ser rápidas Conclusión Bibliografía Apéndices Apéndice A. Concurrencia II Ejemplo cliente/servidor - El servidor - Añadir subprocesos - Observaciones del servidor Conclusión Posibles rutas de ejecución Número de rutas Un examen más profundo Conclusión Conocer su biblioteca - La estructura Executor - Soluciones no bloqueantes - Clases incompatibles con subprocesos Las dependencias entre métodos pueden afectar al código concurrente - Tolerar el fallo - Bloqueo basado en el cliente - Boqueo basado en el servidor Aumentar la producción - Cálculo de producción de un solo subproceso - Cálculo de producción con varios subprocesos Bloqueo mutuo - Exclusión mutua - Bloqueo y espera - No expropiación - Espera circular - Evitar la exclusión mutua - Evitar bloqueo y espera - Evitar la expropiación - Evitar la espera circular Probar código con múltiples subprocesos Herramientas para probar código basado en subprocesos Conclusión Ejemplos de código completos - Cliente/Servidor sin subprocesos - Cliente/Servidor con subprocesos Apéndice B. org.jfree.date.SerialDate Epílogo Índice alfabético