Acabo de leer el enlace del artículo que publicaste, tengo que decir que Fowler ha hecho algunos puntos muy buenos y muchas cosas que dijo, he estado abogando por nuestro equipo durante años.
En mi opinión, si haces un diseño decente, no deberías meterte en lo que se consideraría una situación sin salida. Siempre he visto el software como compuesto por bloques de construcción . Todavía creo en un diseño inicial, pero el objetivo principal no es diseñar el producto completo, sino proporcionar una arquitectura / dirección general para que su equipo pueda visualizar una imagen común en la que todos estamos trabajando. Si tienes un montón de piezas de cubo y triángulo, es útil esbozar cómo se armaría un castillo antes de simplemente comenzar a juntar piezas.
Como vengo de OO land, para mí cada bloque es una clase y la superficie de ese bloque es la interfaz pública (lo que es visible por clases externas o derivadas). Si sigue buenos principios de SOLID, se asegurará de que cada bloque sea extremadamente simple y tenga una interfaz pública intuitiva. Volviendo a mi analogía, desea asegurarse de que el código solo crea formas simples. Cada vez que crea clases, que son demasiado complejas (muchas funciones, muchas variables), crea formas que son difíciles de reutilizar cuando cambian los requisitos.
Estoy de acuerdo con Fowler en que el mayor riesgo / desafío para el diseño evolutivo es que dejes las decisiones de diseño al tiempo de codificación, y esperas que cada desarrollador individual tome esas decisiones. Aquí es donde el sistema puede fallar si no tiene mecanismos de retroalimentación adecuados. Cada vez que se solicita una nueva característica, es extremadamente tentador simplemente encontrar la función que necesita ser extendida, poner algún tipo de condicional dentro de ella y simplemente agregar un montón de código dentro de esa función. Y a veces, esto podría ser todo lo que se necesita, pero esta también es (IMO) la práctica más común que conduce a componentes sin salida. Esto no tiene nada que ver con el diseño evolutivo. Esto es lo que se llama "sin diseño".
Siempre que se tome el tiempo de dar un paso atrás y decir, espere un minuto, esta clase ya tiene 15 variables miembro, permítame extraer 6 de estas y ponerlas en su propia clase autónoma, su software estará compuesto de muy poca luz. Ligero, flexible y reutilizable. Claro, si aparecen los PM y cambian la mitad de los requisitos de productos para usted, es posible que tenga que sacar algunos de sus bloques, volver a colocarlos en el estante y elaborar algunos nuevos (al igual que cuando construye un castillo, es posible que no use todos tus cilindros) Pero en ese punto, eso es solo parte de hacer negocios. Los requisitos cambiaron y al mantener su código flexible y modular, debería poder cambiar su producto para alinearse con su nueva dirección comercial.
Creo que este enfoque evolutivo del diseño funciona con todos los niveles de habilidad del ingeniero. Personalmente, he desarrollado software durante mucho tiempo y antes de que nuestro equipo adoptara una metodología ágil, fui responsable de enviar varios componentes principales de mi PC de desarrollo casi directamente al cliente sin apenas QA. Al mismo tiempo, esos componentes siempre han permanecido flexibles y mantenibles.
Solo estoy tratando de decir que me consideraría relativamente decente en el diseño de software. Al mismo tiempo, si me pidiera que redactara un documento de diseño de 100 páginas, se lo entregara a un codificador y esperara que funcionara, probablemente no podría diseñarme con una bolsa de papel. Al comenzar a trabajar, a veces dibujaba unos pocos diagramas similares a UML (muy simplificados, no en lenguaje completo), pero a medida que comienzo a codificar, refactorizaría según fuera necesario y mi código final nunca se vería como lo dibujé originalmente. Incluso si me paso un mes o dos pensando en cada pequeño detalle, no puedo imaginar que otra persona pueda tomar mis diagramas y crear un software sólido sin modificar el diseño mientras están codificando.
En el otro extremo del espectro, actualmente en mi equipo (ahora ágil y lo apoyo totalmente) tenemos un par de tipos que se unieron a nosotros desde tierras incrustadas donde solo han hecho C durante los últimos 15 años. Obviamente, ayudé con algunas clases iniciales de planificación y diseño, pero también me aseguré de seguir con revisiones periódicas de código y sesiones de lluvia de ideas en las que discutimos aplicaciones de SOLID y principios de diseño. Produjeron un código de espagueti que me hizo encogerme un poco, pero con solo un ligero empujón de mi parte, comenzaron a refactorizar lo que ya se había producido y la parte divertida es que uno de ellos regresó a mí unos días después y dice: Odio para decirlo, pero después de mover ese código, esto parece mucho más legible y comprensible. Callejón sin salida evitado. Punto I ' Lo que intento hacer es que incluso alguien que sea completamente nuevo en OO pueda producir un código algo decente, siempre que tenga un mentor con más experiencia, para recordarle que "diseño evolutivo" no es lo mismo que "no diseño". E incluso algunas de sus clases "más complejas" no dan tanto miedo porque cada clase no tiene tanta responsabilidad (es decir, no tiene tanto código), por lo que lo peor es peor, si esa clase "termina sin salida", nosotros tíralo y escribe una clase de reemplazo que tenga la misma interfaz pública (hasta ahora nunca vi la necesidad de esta contingencia en nada de lo que escribimos y he estado haciendo revisiones de código dos veces por semana).
Como nota final, también creo firmemente en los documentos de diseño (al menos para las condiciones comerciales de mi equipo actual), pero el objetivo principal de nuestros documentos de diseño es la Memoria Organizacional , por lo que los documentos reales se escriben después de que se produce el código y refactorizado. Antes de la codificación, generalmente tenemos una fase de diseño rápida (a veces no tan rápida) en la que esbozamos clases sobre servilletas / mspaint / visio y siempre les recuerdo a las personas que esta fase produce un camino a seguir, no un plan y cuando comienzan a codificar, todo lo que no tiene sentido debe cambiarse. Incluso con estos recordatorios, los tipos más nuevos tienden a intentar volver a encajar el código en el diseño original, sin importar cuán antinatural se sienta incluso para ellos. Esto generalmente aparece en las revisiones de código.
Dang, escribí mucho. Lo siento por eso.