More on this book
Kindle Notes & Highlights
Relación de código con perfiles de investigación
El desarrollador diseña sus bloques funcionales para que los máximos datos realimenten al componente tecnológico, y el investigador construye un algoritmo adaptativo mapeando sus parámetros a las condiciones del contexto.
El investigador centra su esfuerzo en implementar un algoritmo siguiendo el rigor analítico, mientras que el equipo técnico tiene que asegurar que se cumplen unos requisitos de calidad y latencia.
los trabajos de desarrollo e investigación están unidos por el contexto.
Relación de código con perfiles de validación y gestión
Testeo y trazabilidad son por tanto los dos criterios que el desarrollador ha de seguir para comunicarse adecuadamente con estos perfiles.
el desarrollador implementa paquetes o proyectos de test unitarios que se validan en el proyecto de integración continua
La cobertura de código es un indicativo de calidad del producto, pero el valor ideal es aquél que maximiza esfuerzo y sentido común.
otras métricas de calidad de código (complejidad ciclomática, repetición de código,…),
la trazabilidad, la misión del desarrollador es seguir fielmente la metodología de trabajo, y para ello requiere que la compañía de innovación tenga madurez en sus procesos.
Puede parecer que tanta rigurosidad vaya en contra de un manifiesto ágil, pero incluso las certificaciones CMMI ya se mapean con las prácticas ágiles5.
Relación de código con perfiles de despliegue y operación
el criterio de operaciones es mantener el entorno de producción estable y con alta disponibilidad.
la operación de despliegue ha de incluirse en el ciclo de integración continua y así desarrollador e ingeniero de despliegue pueden resolver los problemas de producción desde las primeras fases del producto.
el desarrollador es el responsable de la generación del build del código, por lo que ha de ser riguroso en la definición de las dependencias acorde con la tecnología y usando repositorios comunes
empaquetado es responsabilidad del ingeniero de despliegue que aplica criterios estándar según los entornos (por ejemplo, rpms, dpkgs, etc) y versiona de tal manera que pueda trazarse el paquete respecto al repositorio de código fuente
supone un beneficio a posteriori para todos los miembros del producto.
las salidas que se establecen en el código han de tener suficiente semántica y trazabilidad
apta únicamente para personas con perfil técnico dado que implica eliminar la abstracción de los CMS a costa de un conocimiento más profundo del entorno técnico de trabajo.
Hay ocasiones en las que el código existente es tan confuso que, aunque podrías refactorizarlo, es más fácil empezar desde el principio. Martin Fowler
la arquitectura software que  se plantea en un principio, a menudo necesita flexibilizarse y evolucionar.
El desarrollo tradicional en cascada no tiene en cuenta este hecho en absoluto. La arquitectura se diseña en una etapa inicial del proyecto, a partir de la extracción de requisitos, antes de que se escriba ningún código. Las
metodologías ágiles sí tienen en cuenta esto, y hablan de que la arquitectura es "orgánica" y debe surgir y evolucionar al mismo tiempo que el código, modificándose por medio de refactorizaciones progresivas para adaptarse a los cambios.
la experiencia nos dice que una arquitectura, una vez que ha tomado un camino, no es infinitamente flexible,
Un Reboot es una fase en un punto intermedio de un proyecto software, en el que para continuar evolucionando adecuadamente el sistema, se descarta todo el código realizado hasta el momento, y se vuelve a comenzar con el desarrollo, empezando desde el diseño de la arquitectura.
El primero es discutir desde el punto de vista técnico las ventajas de un reboot frente a la refactorización continua, y demostrar que el coste de abordarlo
El segundo objetivo es ayudar a programadores y jefes de proyecto a realizar estos reboots cuando sea necesario.
La modularidad permite implementar la arquitectura, entendida como partes de un todo las cuales se relacionan entre sí de una forma establecida.
Ocultación de información o encapsulamiento:
Un módulo expone sólo la información que necesita para comunicarse con el resto, mediante un interfaz.
Desacoplamiento:
si tengo implementado un módulo, pero tengo que cambiar su funcionalidad, si no cambio su API puedo volver a hacerlo de nuevo sin afectar el resto del sistema que lo usa.
si los interfaces de las librerías no encajan bien con el resto de la aplicación, podemos ocultar o extender estos interfaces con patrones de diseño como el patrón Wrapper3, o extensiones locales4.
las refactorizaciones sencillamente no bastan. Por ejemplo, con código legacy (heredado) y cuyo conocimiento se ha perdido, el coste de modificar la arquitectura de ese código es enorme.
Permite eliminar acoplamientos del código no deseados, una vez que está claro que la aplicación de cierto patrón de diseño solucionaría cierto problema.
Características del código que pueden necesitarse en cierto momento en muchos puntos del código a nivel horizontal, tienen coste cercano a cero si se implementan en un reboot.
seguridad, autorización, logging, etcétera.
En proyectos de larga duración, permite cambiar las herramientas usadas a las versiones más modernas, de nuevo, con coste casi cero.
Realmente nunca partimos de cero. Es perfectamente legítimo usar el código antiguo para copiar y pegar métodos o incluso clases enteras si cierta parte del código antiguo encaja con la arquitectura objetivo.
es una ocasión para dejar el código limpio, cumplir en todos los casos con las convenciones que se van estableciendo a lo largo de un desarrollo
los ánimos del equipo técnico aumentan.
la necesidad de hacer el reboot es detectada por los programadores,
volverán a tener  un código ágil en el que es agradable trabajar. 
desde el punto de vista técnico si el código necesita el reboot. Deberían
Si el software sigue teniendo una arquitectura reconocible y seguida por todos. 
dividir el trabajo en el equipo sin que sus miembros se estorben unos a otros.
es responsabilidad de los desarrolladores no sólo identificar la necesidad de realizar un reboot, sino también convencer y pelear para que se lleve a cabo. Los desarrolladores son los únicos que pueden ver el problema y los beneficios. No hay que esperar a que el Scrum Master proponga un reboot,
al cliente también le cuesta mucho más dinero pagar por arreglar bugs detectados en producción que en desarrollo.
asegurarse que todas las líneas de las partes críticas son ejecutadas por algún test unitario o varios.
diferencia entre un test unitario y un test de integración.






