Pregunta

Uno de los argumentos frecuentes que escucho por no adherirse a los principios SÓLIDOS en objeto- diseño orientado es YAGNI (aunque el argumentador menudo no llama así):

"Está bien que puse tanto la característica X y Y en función de la misma clase. Es tan simple ¿por qué preocuparse de añadir una nueva clase (es decir, la complejidad)."

"Sí, puedo poner toda mi lógica de negocio directamente en el código de interfaz gráfica de usuario es mucho más fácil y más rápido. Esto siempre será la única interfaz gráfica de usuario y es muy poco probable que importantes nuevos requisitos cada vez entrar".

"Si en el caso poco probable de nuevos requisitos de mi código obtiene demasiado desordenada Todavía puedo refactorizar para el nuevo requisito. Por lo que su argumento '¿Qué pasa si más tarde necesita ...' no cuenta."

¿Cual sería la mayoría de los argumentos convincentes en contra de esta práctica? ¿Cómo puede realmente Mostrar que esta es una práctica costosa, especialmente para alguien que no tiene demasiada experiencia en desarrollo de software.

¿Fue útil?

Solución

El diseño es la gestión y el balance de las compensaciones YAGNI y sólida no son contradictorios:. El primero dice cuando para agregar características, este último dice cómo, pero ambos guiar el proceso de diseño. Mis respuestas, a continuación, a cada uno de sus cotizaciones específicas utilizar los principios de ambos YAGNI y sólido.

  
      
  1. Es tres veces más difícil de construir componentes reutilizables como de un solo uso   componentes.
  2.   
  3. Un componente reutilizable debería ser juzgado en tres diferentes   aplicaciones antes de que sea lo suficientemente general como para aceptar a una reutilización   biblioteca.
  4.   
     

- Robert Glass' reglas de tres , Hechos y errores de Ingeniería de Software

Refactorizando en componentes reutilizables tiene el elemento clave de encontrar primero el mismo propósito en múltiples lugares, y después moverlo. En este contexto, se aplica por YAGNI inlining ese propósito cuando sea necesario, sin preocuparse por la posible duplicación, en lugar de añadir características genéricas o reutilizables (clases y funciones).

La mejor manera, en el diseño inicial, para mostrar cuando YAGNI no se aplica es identificar las necesidades concretas. En otras palabras, hacer algo de refactorización antes de escribir código para mostrar que la duplicación no es solamente posible, sino que ya existe:. Esto justifica el esfuerzo adicional


  

Sí, puedo poner toda mi lógica de negocio directamente en el código de interfaz gráfica de usuario es mucho más fácil y más rápido. Esto siempre será la única interfaz gráfica de usuario y es muy poco probable que signifcativas nuevos requisitos cada vez entrar.

¿Es realmente la única interfaz de usuario? ¿Hay un modo por lotes fondo planeado? ¿Habrá alguna vez una interfaz web?

¿Cuál es su plan de pruebas, y va a ser la prueba de funcionalidad de back-end sin una interfaz gráfica de usuario? Lo que hará que la interfaz gráfica de usuario fácil para poner a prueba, ya que por lo general no quiere estar poniendo a prueba el código externo (como controles GUI-plataforma genérica) y en lugar de concentrarse en su proyecto.

  

Está bien que puse tanto la característica X y Y en función de la misma clase. Es tan simple ¿por qué preocuparse de añadir una nueva clase (es decir, la complejidad).

¿Se puede señalar un error común que debe ser evitado? Algunas cosas son bastante simples, tales como elevar al cuadrado un número (x * x vs squared(x)) por un excesivo-ejemplo sencillo, pero si se puede señalar una alguien error concreto hecho, especialmente en su proyecto o por los de su equipo le puede mostrar cómo una clase o función común evitarán que en un futuro.

  

Si, en el caso poco probable de nuevos requisitos, el código se vuelve demasiado desordenada Todavía puedo refactorizar para el nuevo requisito. Por lo que su "¿Qué pasa si más tarde necesita ..." argumento no cuenta.

El problema aquí es la suposición de "poco probable". ¿Está de acuerdo que es poco probable? Si es así, estás de acuerdo con esta persona. Si no, su idea de que el diseño no está de acuerdo con esta person's-resolver esa discrepancia va a resolver el problema, o al menos le muestre dónde ir después. :)

Otros consejos

Parece que usted está discutiendo con una pared de ladrillos. Soy un gran fan de YAGNI, pero al mismo tiempo, también espero que mi código siempre se utiliza en al menos dos lugares: la aplicación y las pruebas. Es por eso que cosas como la lógica de negocio en el código de interfaz de usuario no funcionan; no se puede separar la lógica de negocio de prueba de código de interfaz de usuario en esa circunstancia.

Sin embargo, a partir de las respuestas que estás describiendo, parece que la persona es simplemente desinteresado en hacer un mejor trabajo. En ese momento, ningún principio se les va a ayudar; que sólo quieren hacer lo mínimo posible. Yo iría tan lejos como para decir que no es YAGNI conducir sus acciones, sino más bien la pereza, y que solos no van a la pereza tiempo (casi nada lata, excepto un administrador de amenaza o la pérdida de un puesto de trabajo).

Me gusta pensar en YAGNI en términos de "medio, no a medias", para usar la frase de 37signals ( https://gettingreal.37signals.com/ch05_Half_Not_Half_Assed.php ). Se trata de limitar su alcance para que pueda centrarse en hacer las cosas más importantes también. No es una excusa para conseguir descuidado.

La lógica de negocio en la interfaz gráfica de usuario se siente a medias para mí. A menos que su sistema es trivial, me sorprendería si su lógica de negocio y la interfaz gráfica de usuario no lo han cambiado de forma independiente, varias veces. Por lo que debe seguir la SRP ( "S" en estado sólido) y refactor -. YAGNI no se aplica, porque ya lo necesite

El argumento sobre YAGNI y complejidad innecesaria aplica absolutamente, si está haciendo un trabajo extra hoy para adaptarse a las necesidades futuras hipotéticas. Cuando los "¿y si después tenemos que ..." escenarios no se materializan, que está pegado con mayores costos de mantenimiento de las abstracciones que ahora se interponen en el camino de los cambios que tiene actualmente. En este caso, estamos hablando de simplificar el diseño mediante la limitación de alcance -. Hacer la mitad, en lugar de ser un medio culo al aire-

No hay una respuesta, o mejor dicho, hay una respuesta ni usted ni su fuerza como interlocutor:. Tanto YAGNI y sólido puede ser enfoques equivocados

El intento de ir para sólidos con un equipo sin experiencia, o un equipo con los objetivos de entrega ajustados prácticamente garantiza que va a terminar con un montón caro, sobre-ingeniería de código ... que no va a ser sólido, justo por encima de ingeniería (aka la bienvenida al mundo real).

El intento de ir YAGNI para un proyecto a largo plazo y esperamos que usted pueda refactorizar tarde sólo funciona hasta cierto punto (también conocido como la bienvenida al mundo real). YAGNI sobresale en la prueba de concepto y manifestantes, consiguiendo el mercado / contrato y luego ser capaz de invertir en algo más sólido.

Se necesitan las dos, en diferentes puntos en el tiempo.

La correcta aplicación de estos principios a menudo no es muy evidente y depende mucho de la experiencia. Que es difícil de obtener si no lo hace usted mismo. Cada programador debería haber tenido experiencias de las consecuencias de hacerlo mal, pero por supuesto que siempre debe ser "no es mi" proyecto.

Explicar a ellos cuál es el problema, si no escuchan y que no están en condiciones de hacer que escuchen, que lo hagan los errores. Si usted es demasiado a menudo el tener que solucionar el problema, se debe pulir su hoja de vida.

En mi experiencia, siempre es una cuestión de criterio. Sí, usted no debe preocuparse acerca de cada pequeño detalle de su aplicación, ya veces se pegue un método en una clase existente es un aceptable, aunque la solución fea.

Es cierto que se puede refactorizar más tarde. El punto importante es que en realidad hacer la refactorización . Así que creo que el problema real no es el compromiso de diseño ocasional, pero posponiendo refactorización vez que se pone de manifiesto que hay un problema. En realidad va a través con él es la parte más difícil (al igual que con muchas cosas en la vida ...).

En cuanto a sus puntos individuales:

  

Está bien que puse tanto la función X   y cuentan con Y en la misma clase. Eso   es tan simple ¿por qué preocuparse de añadir un nuevo   clase (es decir, complejidad).

Me recuerda que tener todo en una clase es más complejo (debido a que la relación entre los métodos es más íntimo y más difícil de entender). Tener muchas clases pequeñas no es complejo. Si siente que la lista es llegar a tiempo, sólo organizarlos en paquetes, y se le multa :-). En lo personal, he encontrado que simplemente dividir una clase en dos o tres clases puede ayudar mucho con la lectura, sin ningún cambio adicional.

No tenga miedo de las clases pequeñas, que no muerden; -).

  

Sí, puedo poner toda mi lógica de negocio   directamente en el código GUI es mucho   más fácil y más rápido. Este será siempre   sea ??la única interfaz gráfica de usuario y es muy   poco probable que la nueva signifcant   exigencias cada vez entrarán.

Si alguien puede decir "que es muy poco probable que signifcativas nuevos requisitos cada vez entrar". con una cara seria, creo que la persona realmente, realmente necesita una revisión de la realidad. Ser franco, pero suave ...

  

Si en el caso improbable de nuevo   requisitos de mi código que baje demasiado   desordenado todavía puedo refactorizar para el   nuevo requerimiento. Así que tu '¿Y si   más tarde necesidad de ...' argumento no hace   recuento

Eso tiene algún mérito, pero sólo si realmente lo hacen refactor más tarde. Así que aceptarlo, y los mantienen su promesa: -).

sólidos principios permiten que el software para adaptarse al cambio - en ambos requisitos y cambios techical (nuevos componentes, etc), dos de sus argumentos son los requisitos para que no cambian:

  • "es muy poco probable que signifcativas nuevos requisitos cada vez entrar".
  • "Si en el caso poco probable de nuevos requisitos"

Podría esto ser cierto?

No hay sustituto para la experiencia cuando se trata de los diversos gastos de desarrollo. Para muchos practicantes Creo que hacer las cosas en el mal, difícil de mantener manera que nunca se ha traducido en problemas para ellos (¡Hey! Estabilidad en el empleo). A largo plazo de un producto Creo que estos gastos se vuelven claras, pero hacer algo acerca de ellos antes de tiempo es el trabajo de otro.

Hay algunas otras grandes respuestas aquí.

Es comprensible, flexible y capaz de correcciones y mejoras siempre son cosas que está va a necesitar. De hecho, YAGNI supone que puede volver y añadir nuevas características cuando se considere necesario, con relativa facilidad, porque nadie va a hacer algo loco como bunging funcionalidad irrelevante en una clase (YAGNI en esa clase!) O empujar la lógica de negocio a la lógica de interfaz de usuario .

No puede haber momentos en los que lo que parece loco ahora era razonable en el pasado - a veces las líneas de límite de la interfaz de usuario vs negocio o entre diferentes conjuntos de responsabilidades que deberían estar en una clase diferente, no tan claro, o incluso mover son. Puede haber momentos en los que es absolutamente necesario en el tiempo 2 horas 3 horas de trabajo. Hay momentos en que la gente simplemente no hacen la decisión correcta. Por estas razones descansos ocasionales en este sentido va a pasar, pero van a conseguir de la manera de utilizar el principio YAGNI, no ser una de las causas de la misma.

Pruebas de calidad de la unidad, y no pruebas unitarias medias de las pruebas de integración, código necesidad de que se adhiere a bueno. No necesariamente el 100%, de hecho, rara vez es así, pero en su ejemplo el relleno de dos funciones en una clase hará que la unidad de prueba más difícil, rompe el principio de la responsabilidad individual, y hace que el mantenimiento del código de novatos del equipo mucho más difícil (ya que es mucho más difícil de comprender) .

Con las pruebas unitarias (suponiendo una buena cobertura de código) podrás función de perfeccionar por 1 salvo y seguro que no va a romper característica 2, pero sin pruebas de unidad y con las características en una misma clase (simplemente para estar en perezosos tu ejemplo) refactorización es arriesgado, en el mejor, desastroso en el mejor.

En pocas palabras: seguir el principio KIS (mantenerlo simple), o para el intelectual el principio KISS (kis estúpida). Tome cada caso en el mérito, no hay una respuesta global, pero siempre en cuenta si otros codificadores necesitan leer / mantener el código en el futuro y el beneficio de las pruebas unitarias en cada escenario.

tldr;

SOLID asume, a entender (un poco al menos), los futuros cambios en el código, SRP WRT. Me gustaría decir que está siendo optimistas acerca de la capacidad de predecir. YAGNI por el contrario, asume la mayor parte de las veces que no conoce la dirección futura del cambio, que es pesimista sobre la capacidad de predecir.

De aquí se sigue que / SRP SÓLIDO le pide a formar clases para el código de tal manera que tendrá una única razón para el cambio. P.ej. un pequeño cambio GUI o cambio ServiceCall.

dice YAGNI (si quieres la fuerza que se aplica en este escenario), ya que no se sabe lo que va a cambiar, y si un cambio de interfaz gráfica de usuario provocará un cambio GUI + ServiceCall (de manera similar Un cambio backend causando GUI + cambio SeviceCall), sólo hay que poner todo el código que, en una sola clase.

Respuesta larga:

Leer el libro 'desarrollo ágil de software, principios, patrones y prácticas'

Estoy poniendo breve extracto de ella sobre / SRP SOLID: "Si, [...] la aplicación no está cambiando de maneras que causan las dos responsabilidades a los cambios en diferentes momentos, no hay necesidad de separarlos. De hecho, separándolos olerían de una complejidad innecesaria.

Hay un corolario aquí. Un eje de cambio es un eje de cambio sólo si se producen los cambios. No es prudente aplicar SRP-o cualquier otro principio, para el caso, si no hay ningún síntoma. "

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top