Estoy trabajando en un proyecto de software donde tenemos que construir tres API. Uno para el canal de banca doméstica , uno para el canal de la agencia y un tercero para el canal móvil .
La API de la agencia es la más completa ya que tiene todas las funcionalidades ... luego una API de inicio un poco más pequeña y luego una API móvil.
Los arquitectos aquí crearon una capa común (servicios EJB de canal cruzado compartidos por todas las API). Pero entonces las API son diferentes.
No hay una gran diferencia por ahora entre las API. El gran equipo comenzó con el canal de la agencia, y ahora lo estamos adaptando para el canal local. Solo estamos enriqueciendo objetos específicamente para nuestra aplicación de inicio. De lo contrario, el código es 95% similar entre las API. La API está construida sobre Spring MVC , y tiene (controladores, modelos y algunas utilidades).
Básicamente, los controladores están haciendo el mapeo de BO a ChannelObject (me parece que no es el lugar correcto para hacerlo), y algunas utilidades y serializadores adicionales. Todo está duplicado por ahora. Dicen que la razón de la duplicación es que quieren que las API sean independientes. "¡Si mañana queremos un comportamiento diferente para el hogar que la agencia o el móvil, no tendremos problemas!"
¿Hay algún caso en el que debamos aceptar código duplicado?
Respuestas:
La duplicación puede ser lo correcto, pero no por este motivo.
Decir "podríamos querer que estos tres lugares en la base del código se comporten de manera diferente aunque en este momento sean idénticos" no es una buena razón para la duplicación a gran escala. Esta noción podría aplicarse a todos los sistemas y podría usarse para justificar cualquier duplicación, lo que obviamente no es razonable.
La duplicación debe tolerarse solo cuando eliminarla sería, en general, más costoso ahora por alguna otra razón (no puedo pensar en una buena en este momento, pero tenga la seguridad de que puede haber una: prácticamente todo en programación es una compensación en lugar de un ley).
Para lo que está haciendo, la solución correcta podría ser, por ejemplo, extraer el comportamiento que está duplicado en este momento en una Estrategia o algún otro patrón que modele el comportamiento como clases y luego use tres instancias de la misma clase. De esa manera, cuando no quiere cambiar el comportamiento de uno de los tres lugares, es suficiente con crear una nueva estrategia y cree una instancia que en un solo lugar. De esa manera, solo tiene que agregar algunas clases y dejar el resto de la base de código casi intacta.
fuente
Sandi Metz, una reconocida ingeniera de software y autora en el ecosistema de Ruby, tiene una excelente publicación de blog y una charla en la que también habla sobre la relación entre la duplicación y la abstracción. Ella llega a la siguiente conclusión
Y estoy completamente de acuerdo con ella. Déjame darte más contexto a esta cita. A veces, encontrar la abstracción correcta es muy difícil. En tales casos, es tentador ir a cualquier abstracción para reducir la duplicación. Pero más tarde puede descubrir que su abstracción no es válida para todos los casos. Sin embargo, es costoso cambiar todo nuevamente y tomar una ruta diferente (para una explicación mucho mejor, ¡mira cómo habla!).
Entonces, sí, para mí, hay casos excepcionales, donde aceptar la duplicación es la decisión correcta, especialmente cuando no está seguro de lo que vendrá y es probable que los requisitos cambien. De su publicación, supongo que ahora hay mucha duplicación, pero sus colegas sugieren que esto podría cambiar y no acoplar ambas aplicaciones entre sí. En mi opinión, este es un argumento válido y no se puede ignorar en general.
fuente
Si la gente comienza a razonar sobre el diseño con las palabras "si mañana" , esto es a menudo una gran señal de advertencia para mí, especialmente cuando el argumento se usa para justificar una decisión que incluye trabajo y esfuerzo adicionales, por lo que nadie sabe realmente si esto alguna vez pagar, y que es más difícil de cambiar o revertir que la decisión opuesta.
La duplicación de código reduce el esfuerzo solo a corto plazo, pero aumentará los esfuerzos de mantenimiento casi de inmediato, proporcionalmente a la cantidad de líneas de código duplicadas. Tenga en cuenta también que una vez que se duplica el código, será difícil eliminar la duplicación cuando resulte que esta fue una decisión incorrecta, mientras que si uno no duplica el código ahora, aún es fácil introducir la duplicación más tarde si se queda pegado a DRY Fue la decisión equivocada.
Dijo que, en organizaciones más grandes, a veces es beneficioso favorecer la independencia de los diferentes equipos sobre el principio DRY. Si eliminando la duplicación extrayendo el 95% de las partes comunes de las API dos, un nuevo componente conduce a un acoplamiento de dos equipos independientes, esta podría no ser la mejor decisión. Por otro lado, si tiene recursos limitados y solo habrá un equipo que mantenga ambas API, estoy seguro de que será de su interés no crear ningún esfuerzo doble y evitar cualquier duplicación innecesaria de código.
Tenga en cuenta además que hace una diferencia si las API "Home" y "Agency" son utilizadas exclusivamente por aplicaciones completamente diferentes, o si uno puede intentar escribir una compilación de componentes sobre esas API que también se pueden usar en un contexto "Home" como en un contexto de "Agencia". Para esta situación, tener las partes comunes de las API exactamente idénticas (que solo puede garantizar si las partes comunes no están duplicadas), hará que el desarrollo de dicho componente sea mucho más fácil.
Entonces, si resulta que habrá sub equipos realmente diferentes, cada uno responsable de cada API, cada uno con un horario y recursos diferentes, entonces es hora de duplicar el código, pero no "por si acaso".
fuente
Duplicación para evitar el acoplamiento . Digamos que tiene dos sistemas grandes y los obliga a usar la misma biblioteca. Puede estar acoplando el ciclo de lanzamiento de ambos sistemas. Puede que esto no sea tan malo, pero digamos que un sistema necesita introducir un cambio. El otro necesita analizar el cambio y puede verse afectado. A veces puede romper cosas. Incluso si ambas partes pueden coordinar los cambios, podría haber muchas reuniones, pasando por gerentes, pruebas, dependencias y el final del pequeño equipo autónomo.
Entonces está pagando el precio del código duplicado para ganar autonomía e independencia.
fuente