principio kiss bduf design yagni

design - kiss - ¿Cuándo violar YAGNI?



principio yagni (8)

El "principio" de YAGNI establece que, de todos modos, no debe centrarse en proporcionar funcionalidad antes de necesitarlo ya que "no lo va a necesitar".

Normalmente tiendo a usar el sentido común por encima de cualquier regla, pase lo que pase, pero a veces siento que es útil diseñar en exceso o probar algo en el futuro si tienes buenas razones, incluso si es posible que nunca lo uses.

El caso real que tengo en mis manos ahora es más o menos así:

Tengo una aplicación que debe ejecutarse sobre un protocolo de comunicación propietario simple (nivel 4 de OSI). Este protocolo tiene un conjunto de características deseables (como la siguiente especificación NORM) que proporcionan robustez a la aplicación pero que no son estrictamente necesarias (la multidifusión UDP podría funcionar aceptablemente).

También está el hecho de que la aplicación probablemente (pero no seguramente) sea utilizada por otros clientes en el futuro que no tendrán acceso a la solución patentada y, por lo tanto, necesitarán otra solución. Sé de hecho que la probabilidad de que otro cliente para la aplicación sea alto.

Entonces, ¿qué estás pensando? ¿Debo diseñar para el protocolo patentado y dejar la refactorización, la extracción de interfaz, etc. cuando realmente lo necesito o debo diseñar pensando ahora en el futuro (no tan lejano)?

Nota: Para que quede claro, estoy interesado en escuchar todo tipo de opiniones sobre la pregunta general (cuándo violar YAGNI) pero realmente me gustaría recibir algunos consejos o ideas sobre mi dilema actual :)


Creo que YAGNI podría ser inapropiado cuando quieres aprender algo :) YAGNI es bueno para los profesionales, pero no para los estudiantes. Cuando quieres aprender, siempre lo necesitarás.


Creo que es bastante simple y obvio:

Viole a YAGNI cuando sepa que, con toda seguridad, lo va a necesitar


Estoy de acuerdo con Gishu y Nick.

Diseñar una parte de un protocolo más tarde a menudo lleva a pensamientos como "maldición, debería haber hecho esto de esa manera, ahora tengo que usar esta fea solución"

Pero también depende de quién se conectará con este protocolo.
Si su control termina y cambia de versión al mismo tiempo , siempre puede refactorizar el protocolo más tarde como lo haría con una interfaz de código normal.

Sobre la implementación posterior de las características adicionales del protocolo, descubrí que la implementación del protocolo ayuda mucho a validar su diseño, por lo que al menos puede querer hacer una muestra de código simple fuera de producción para probarla, si necesita el diseño para ser oficial.


Estructurar bien su programa (abstracción, etc.) no es algo a lo que YAGNI se aplica. Siempre quieres estructurar bien tu código.

Solo para aclarar, creo que su situación actual se debe a la aplicación excesiva de YAGNI. Estructurar su código de tal forma que tenga una biblioteca reutilizable para usar este protocolo es una buena práctica de programación. YAGNI no aplica.


La razón por la que YAGNI aplica al código es que el costo del cambio es bajo. Con el código bueno y bien refactorizado agregar una característica más tarde es normalmente barato. Esto es diferente de decir construcción.

En el caso de los protocolos, agregar cambios más tarde generalmente no es barato. Las versiones antiguas se rompen, puede provocar fallas de comunicación y una matriz de prueba N ^ 2, ya que tiene que probar cada versión con cada otra versión. Compare esto con bases de código individuales donde las nuevas versiones solo tienen que funcionar consigo mismas.

Entonces, en su caso, para el diseño del protocolo, no recomendaría YAGNI.


No me preocuparía El hecho de que tenga conocimiento de "YAGNI" significa que ya está pensando de forma pragmática.

Yo diría que, independientemente de lo que se publique aquí, es estadísticamente más probable que se presente un código mejor que alguien que no está analizando sus prácticas de la misma manera.


En mi humilde opinión

  • Yo diría que primero vaya YAGNI. Haz que funcione sin la especificación NORM usando '' lo más simple que funcionaría ''.
  • Luego compare si el costo de hacer los "cambios de diseño" en el futuro es significativamente mayor que realizar el cambio ahora. ¿Tu solución actual es reversible ? Si puede hacer el cambio fácilmente mañana o después de un par de meses, no lo haga ahora. Si no necesita tomar una decisión de diseño irreversible ahora ... demore hasta el último momento responsable (para que tenga más información para tomar una mejor decisión)

Para cerrar si sabes con un grado considerable de certeza de que algo está en el horizonte y agregarlo más adelante va a ser un dolor, no seas un diseño de avestruz.
por ejemplo, sé que se necesitarían registros de diagnóstico antes de que el producto se envíe. Agregar el código de registro después de un mes sería mucho más esfuerzo que sumarlo hoy mientras escribo cada función ... así que este sería un caso en el que anularía YAGNI aunque no necesite registros en este momento.

See-also: Los libros magros de T. & M. Poppendieck son mejores para explicar el dilema de la viñeta n. ° 2 anterior.


Hay algunos casos en los que tiene sentido ir en contra de la intuición de YAGNI.

Aquí hay algunos:

Siguiendo las convenciones de programación. Especialmente contratos de clase base e interfaz. Por ejemplo, si una clase base que hereda proporciona un método GetHashCode y un método Equals, anula Igual pero no GetHashCode rompe las reglas documentadas por la plataforma que los desarrolladores deben seguir cuando anulan Equals. Se debe seguir esta convención incluso si descubre que GetHashCode en realidad no se llamará. No anula GetHashCode es un error, incluso si no hay una forma actual de provocarlo (que no sea una prueba artificial). Una versión futura de la plataforma podría presentar llamadas a GetHashCode. O bien, otro programador que haya analizado la documentación (en este ejemplo, la documentación de la plataforma para la clase base que está heredando) podría esperar legítimamente que su código se adhiera sin examinar su código. Otra forma de pensar sobre esto es que todo el código y la documentación aplicable deben ser coherentes, incluso con documentación escrita por otros, como la proporcionada por el proveedor de la plataforma.

Soporte de personalización. Particularmente por desarrolladores externos que no modificarán su código fuente. Debe descubrir e implementar puntos de extensión adecuados en su código para que estos desarrolladores puedan implementar todo tipo de funcionalidad de complemento que nunca se le pasó por la cabeza. Desafortunadamente, es normal que agregue algunas funciones de extensibilidad que pocos o ningún desarrollador externo utilizan en última instancia. (Si es posible discutir los requisitos de extensibilidad con todos los desarrolladores externos antes de tiempo o usar ciclos frecuentes de desarrollo / lanzamiento, genial, pero esto no es factible para todos los proyectos).

Afirmaciones, comprobaciones de depuración, failsafes, etc. Dicho código no es realmente necesario para que su aplicación funcione correctamente, pero ayudará a garantizar que su código funcione correctamente ahora y en el futuro cuando se realicen las revisiones.