Acoplamiento de código introducido por DRY y OOD

14

Estoy buscando orientación sobre el acoplamiento DRY vs Código. No me gusta duplicar mi código y tampoco me gusta el acoplamiento de código entre módulos no relacionados. Así que refactorizo el código duplicado si encuentro un código idénticamente duplicado un año después de que se introdujo la duplicación. Sin embargo, he experimentado cada vez más situaciones en las que el mundo real es mucho más impredecible y, después de refactorizar el código, surgen situaciones que requieren volver a codificar el código.

Por ejemplo, si tuviera un código para manejar automóviles de gasolina, SUV de gasolina, automóviles eléctricos y SUV eléctrico, digamos que he refactorizado código duplicado en la jerarquía de "gasolina" y la jerarquía de "eléctrico", ambos descendiendo del "vehículo" jerarquía. Hasta ahora tan bueno. Y luego, mi empresa presenta un automóvil híbrido y un Semi híbrido, que requerirían cambios centrales en mi jerarquía original. Tal vez requeriría una "composición" entre la gasolina y las jerarquías eléctricas.

Claramente, la duplicación de código es mala porque aumenta el tiempo necesario para implementar un cambio común a todos los productos anteriores. Pero el código común de refactorización hace que sea igualmente difícil introducir variaciones específicas del producto, y conduce a muchos "saltos de clase" cuando uno tiene que encontrar la línea de código para corregir un error: un cambio en una clase primaria de nivel superior podría desencadenar errores de regresión entre todos los descendientes.

¿Cómo se logra un equilibrio óptimo entre el acoplamiento de código DRY y no deseado?

    
pregunta user2549686 01.06.2018 - 08:47

3 respuestas

8
  

digamos que he refactorizado código duplicado en la jerarquía de "gasolina" y   La jerarquía "eléctrica", ambas descendiendo del "vehículo".   jerarquía. Hasta ahora tan bueno.

     

Y luego, mi empresa introduce un híbrido   Automóvil y un Semi híbrido - eso requeriría cambios centrales a mi original   la propia jerarquía. Tal vez requeriría "composición" entre la   La gasolina y las jerarquías eléctricas.

Creo que esta es una de las razones principales por las que las personas se están moviendo hacia la composición sobre la herencia.

La herencia lo obliga a realizar una gran reestructuración cuando tiene un cambio conceptual como el que describe.

Cuando la reestructuración es 'demasiado grande / difícil', la gente escribe un código duplicado para evitarlo.

En lugar de remover el duplicado al mover el código a la cadena de herencia, puede moverlo a una clase o servicio auxiliar y luego inyectar esa clase como parte de una composición donde sea necesario.

Si el diseño resultante es OOP está abierto a debate

    
respondido por el Ewan 01.06.2018 - 12:26
4

Usted tiene razón, siguiendo el principio DRY, puede aumentar el acoplamiento entre módulos no relacionados de otra manera. Especialmente en sistemas de software más grandes, esto puede llevar a situaciones en las que no seguir DRY puede ser la mejor alternativa.

Lamentablemente, su ejemplo no es adecuado para demostrar esto: los problemas descritos allí son causados por errores clásicos en el uso subóptimo de la herencia de incorrecto . Sin embargo, por lo que he escrito anteriormente, no importa si refactoriza el código común a una clase base común o a la clase auxiliar (composición). En ambos casos, uno podría verse obligado a colocar el código común en una biblioteca L y hacer referencia a esa biblioteca desde dos programas A y B que anteriormente no estaban relacionados.

Supongamos que A y B no estaban relacionados antes, se pueden versionar, lanzar y desplegar de forma independiente. Sin embargo, al colocar un código común en una biblioteca compartida L, los nuevos requisitos para A pueden inducir cambios en L, que ahora pueden causar cambios en B. Por lo tanto, esto causa la necesidad de pruebas adicionales y, probablemente, un nuevo ciclo de implementación y despliegue para B.

Entonces, ¿cómo puede manejar esta situación, si no está dispuesto a abandonar el principio DRY? Bueno, hay algunas tácticas bien conocidas para abordar esto:

  1. Mantenga A, B y L como parte del mismo producto, con un número de versión común, un proceso común de compilación, lanzamiento e implementación, con un alto grado de automatización

  2. o haga de L un producto por sí solo, con números de versión menores (sin cambios incompatibles) y números de versión principales (que quizás contengan cambios de última hora), y A y B permiten que cada uno haga referencia a una línea de versión diferente de L.

  3. Haz que L sea lo más SÓLIDO posible, y cuida la compatibilidad hacia atrás. Cuantos más módulos en L puedan reutilizarse sin modificación (OCP), menos probabilidades habrá de que se produzcan cambios. Y los otros principios en "SOLID" están ayudando a apoyar esa meta.

  4. Use pruebas automáticas especialmente para L, pero también para A y B.

  5. Tenga cuidado con lo que ingresa en L. La lógica de negocios que debería existir solo en un lugar en un sistema es un buen candidato. Las cosas que simplemente "se parecen" y que pueden variar de manera diferente en el futuro son malos candidatos.

Tenga en cuenta que cuando A y B son desarrollados, mantenidos y evolucionados por equipos diferentes, no relacionados, el principio DRY se vuelve bastante menos importante: DRY tiene que ver con la capacidad de mantenimiento y la capacidad de evolución, pero dejar que dos equipos diferentes proporcionen un esfuerzo de mantenimiento individual puede ser a veces más efectivo que atando sus productos juntos debido a un poco de reutilización.

Así que al final, es una compensación. Si desea seguir el principio DRY en sistemas más grandes, necesita invertir mucho más esfuerzo para crear componentes robustos y reutilizables, generalmente más de lo que espera. Debes confiar en tu juicio cuando valga la pena y cuando no.

    
respondido por el Doc Brown 02.06.2018 - 09:23
2

DRY es otra regla estructural. Eso significa que si lo llevas a los extremos es tan malo como si lo ignoraras. Aquí hay una metáfora para sacarte de la mentalidad estructural.

Ama a tus gemelos. Mata a los clones.

Cuando ciegas y pegas ciegamente para evitar teclear, estás creando clones sin pensar. Seguro que hacen lo que quieres pero te pesan porque ahora cambiar ese comportamiento es muy costoso.

Cuando reproduces un comportamiento idéntico con un código idéntico debido a una responsabilidad diferente, sucede que ahora tenemos la misma necesidad, pero eso puede estar sujeto a diferentes cambios, tienes un gemelo que debería ser libre de cambiar y crecer como persona a medida que avanza el tiempo.

Puedes escanear su ADN (código) todo lo que quieras. Los clones y los gemelos son difíciles de diferenciar si lo único que haces es mirarlos. Lo que necesitas es entender el contexto en el que viven. Por qué nacieron. Lo que probablemente será su destino final.

Digamos que trabajas para la empresa ABC. Está dirigido por tres ejecutivos de la empresa, A, B y C. Todos ellos quieren que usted cree un producto de software, pero cada uno tiene sus propios departamentos. Todos quieren que empieces pequeño. Solo da un mensaje simple por ahora. Así que escribes "Hola mundo".

A lo odia, quiere que pongas el nombre de la compañía allí.

A B le encanta, quiere que lo dejes solo y agregues el nombre de la empresa a una pantalla de inicio.

C solo quiere una calculadora y pensó que el mensaje era solo una forma de comenzar.

De lo que está seguro, estos tipos tienen ideas muy diferentes de lo que trata este proyecto. A veces van a estar de acuerdo. A veces te van a llevar en diferentes direcciones.

Cuando duplicas código porque estás creando la posibilidad de que ese código varíe independientemente, estás creando un gemelo. Cuando duplicas código porque escribir es sencillo, copiar y pegar es fácil, estás creando clones malvados.

A, B y C son maestros diferentes que su código debe servir. Ninguna línea de código puede servir a más de un maestro por mucho tiempo.

    
respondido por el candied_orange 01.06.2018 - 16:13

Lea otras preguntas en las etiquetas