¿Cuándo se debe eliminar la complejidad?

14

La introducción prematura de la complejidad mediante la implementación de patrones de diseño antes de que sean necesarios no es una buena práctica.

Pero si sigue todos (o incluso la mayoría de) los principios SÓLIDOS y utiliza patrones de diseño comunes, introducirá cierta complejidad a medida que se agreguen o cambien características y requisitos para mantener su diseño tan sostenible y flexible como sea necesario.

Sin embargo, una vez que se introduce esa complejidad y funciona como un campeón, ¿cuándo la eliminas?

Ejemplo. Tengo una solicitud escrita para un cliente. Cuando se creó originalmente allí, donde hay varias formas de dar aumentos a los empleados. Utilicé el patrón estratégico y la fábrica para mantener todo el proceso limpio y agradable. Con el tiempo, ciertos métodos de aumento fueron agregados o eliminados por el propietario de la aplicación.

El tiempo pasa y el nuevo dueño se hace cargo. Este nuevo propietario es duro, mantiene todo simple y solo tiene una sola forma de dar un aumento.

La complejidad que necesita el patrón de estrategia ya no es necesaria. Si codificara esto a partir de los requisitos tal como están ahora, no introduciría esta complejidad adicional (pero asegúrese de poder introducirla con poco o ningún trabajo si fuera necesario).

Entonces, ¿elimino la implementación de la estrategia ahora? No creo que este nuevo propietario cambie la forma en que se otorgan los aumentos. Pero la aplicación en sí ha demostrado que esto podría suceder.

Por supuesto, este es solo un ejemplo en una aplicación donde un nuevo propietario se hace cargo y ha simplificado muchos procesos. Podría eliminar docenas de clases, interfaces y fábricas y hacer que toda la aplicación sea mucho más simple. Tenga en cuenta que la implementación actual funciona bien y el propietario está contento con ella (y sorprendido e incluso más feliz de que pude implementar sus cambios tan rápido debido a la complejidad discutida).

Admito que una pequeña parte de esta duda se debe a que es muy probable que el nuevo propietario ya no me use. Realmente no me importa que alguien más se haga cargo de esto, ya que no ha sido un gran generador de ingresos.

Pero me importan 2 cosas (relacionadas)

  1. Me importa un poco que el nuevo responsable tenga que pensar un poco más cuando intente comprender el código. La complejidad es complejidad y no quiero enojar al psico maníaco que viene detrás de mí.

  2. Pero aún más me preocupa que un competidor vea esta complejidad y piense que solo implemento patrones de diseño para aumentar mis horas de trabajo. Luego, difundir este rumor para dañar mis otros asuntos. (He escuchado esto mencionado).

Entonces...

En general, ¿debería eliminarse previamente la complejidad necesaria aunque funcione y ha habido una necesidad históricamente demostrada de la complejidad pero no tiene indicios de que será necesaria en el futuro?

Incluso si la pregunta anterior generalmente se responde "no", ¿es prudente eliminar esta complejidad "innecesaria" si se entrega el proyecto a un competidor (o extraño)?

ElGringoGrande
fuente

Respuestas:

7

De alguna manera, creo que esto es en gran medida una decisión comercial y no necesariamente basada en el código en sí. Algunas cosas a considerar:

  • ¿Le pagan para hacer los cambios?
  • ¿El código funciona actualmente como se esperaba?
  • ¿Hay algún problema de seguridad o rendimiento con el código tal como está?
  • ¿El monto de la deuda técnica supera el costo de arreglarlo?
  • ¿Qué es probable que suceda de manera realista si deja el código como está?
  • ¿Cuáles son los problemas futuros que podrían surgir con o sin una refactorización?
  • ¿Qué grado de responsabilidad tiene el código para usted y su empresa?

Estás en la mejor posición para responder esas preguntas. Sin embargo, según su descripción, no sé si me molestaría en refactorizar y simplificar las cosas, ya que no parece que valga la pena su tiempo. Si actualmente funciona, el cliente está contento y no le gusta que le paguen por actualizar todo, entonces déjelo y trabaje en una actividad que genere ingresos.

En resumen, realice un análisis de costo-beneficio y una evaluación de riesgos de ambos caminos y tome el curso de acción más seguro, más eficiente y más rentable.

VirtuosiMedia
fuente
6

¿No es eliminar este código y reemplazarlo con algo simple para la futura facilidad de codificación de una característica que el cliente debe considerar y pagar?

Es posible que tenga algo útil de lo que otro desarrollador podría aprender, pero no es probable que encuentre la aplicación de otro cliente para conectarla.

Cotillear sobre el código de la competencia no es algo que pueda evitar. Se verán tontos tratando de reclutar clientes negativamente.

JeffO
fuente
+1 para "y pagar". Si va a pedirle al cliente que pague el cambio, debe permitir que el cliente decida si realiza el cambio. Observe que dejar el sistema flexible agrega cierta cantidad al valor de reventa del negocio, ya que le permitirá al PROXIMO propietario realizar cambios más fácilmente.
John R. Strohm
3

Un dicho común es: "Si no está roto, no lo arregles".

Hay varias razones detrás de esta regla. Algunos de ellos podrían ser que la "simplificación" correrá el riesgo de introducir errores nuevos, diferentes y posiblemente más grandes, podría quitarle una cantidad cada vez mayor de tiempo de desarrollo de otros esfuerzos más valiosos y podría ser un cambio completamente incorrecto para alguna oportunidad de negocio futura inesperada que surge

Si hay suficiente valor comercial para que este código sea portátil y más fácil de mantener, entonces decida si ese valor es realmente suficiente para considerar que el código actual está "roto". Bien podría ser, si se planea una expansión comercial importante, o si sospecha que hay un error latente oculto en la complejidad que podría derribar el negocio.

hotpaw2
fuente
2

En primer lugar, si la aplicación ya fue tomada una vez por un nuevo propietario, puede volver a ocurrir. Y el próximo propietario puede comenzar nuevamente a usar esa complejidad de la que no se beneficia en este momento.

Además de esto, los cambios no triviales en el código de trabajo siempre conllevan un riesgo, por lo tanto (como otros han señalado) el cliente debe estar de acuerdo con ellos (y pagarlos). Si la complejidad "extra" actual no causa ningún inconveniente notable y medible (como problemas de rendimiento), no hay una razón sólida para eliminarlo.

Los clientes (potenciales) que (no) lo contratan basándose únicamente en los rumores de los competidores no son en mi humilde opinión, de todos modos, a menos que tenga una necesidad desesperada de ingresos. Tiene buenas y lógicas razones por las que implementó la aplicación de la manera que lo hizo, y cualquier cliente serio probablemente lo entienda. Alguien que no lo haga, o que ni siquiera se moleste en preguntarle, probablemente le causará más problemas en el camino de lo que vale la pena.

Péter Török
fuente
1

En general, ¿debería eliminarse previamente la complejidad necesaria aunque funcione y ha habido una necesidad históricamente demostrada de la complejidad pero no tiene indicios de que será necesaria en el futuro?

No.

Incluso si la pregunta anterior generalmente se responde "no", ¿es prudente eliminar esta complejidad "innecesaria" si se entrega el proyecto a un competidor (o extraño)?

No. ¿Por qué perder su tiempo arreglando la prioridad baja funciona así? No hay daño para el código que se queda allí.

En cuanto a su pregunta: ¿Cuándo debería eliminarse la complejidad?

Mi opinión es que, si no está roto, no lo arregles .

Pan pizza
fuente
0

Para poder eliminar la complejidad, lo siguiente debe ser cierto:

  1. La pieza eliminada debe ser independiente del programa. Si hay dependencias del programa circundante al código en cuestión, simplemente eliminar la complejidad no funcionará
  2. Desafortunadamente, si parece complejidad, es muy probable que las piezas no sean independientes y que las dependencias rompan su programa cuando quite la pieza.
  3. Eliminar todas las dependencias llevará tiempo, por lo que es necesario tener en cuenta el tiempo para estimar si la operación vale la pena.
  4. La mayoría de las veces no vale la pena, pero decidirá no hacer que ningún código nuevo use el antiguo
tp1
fuente
Son independientes y en realidad los eliminé y pasé todas las pruebas de unidad / integración / regresión. La complejidad es simplemente una implementación de la Estrategia que requiere al menos una interfaz y una implementación concreta de esa interfaz. En las dos docenas de lugares donde el nuevo propietario ha simplificado todo se podría hacer con una sola clase.
ElGringoGrande
0

Creo que hay algo más grande en el trabajo aquí ... Escalabilidad

De lo que estás hablando se llama escalabilidad . No importa si el código es complejo, importa si la aplicación puede evolucionar en función de las nuevas reglas comerciales o las reglas comerciales cambiadas. ¿Qué sucede si el próximo propietario quiere algo totalmente diferente?

Entonces, digo que conserve el código y lo documente. Es una característica de cómo se puede utilizar la aplicación.

Michael Riley - también conocido como Gunny
fuente
0

En general, ¿debería eliminarse previamente la complejidad necesaria aunque funcione y ha habido una necesidad históricamente demostrada de la complejidad pero no tiene indicios de que será necesaria en el futuro?

Hay un esfuerzo y un riesgo para eliminar la complejidad. Si eso es mayor que el esfuerzo adicional y el riesgo de mantener el código excesivamente complejo, entonces manténgalo. De lo contrario, lo eliminas. Sin embargo, es difícil estimar esos riesgos.

Agregaría que puede mitigar el riesgo de un mantenimiento más difícil al documentar por qué usó la Estrategia de patrón de diseño en primer lugar, en el código. Personalmente, creo que cualquier patrón de diseño debe ser trazable a un requisito explícito (funcional o no funcional).

Incluso si la pregunta anterior generalmente se responde "no", ¿es prudente eliminar esta complejidad "innecesaria" si se entrega el proyecto a un competidor (o extraño)?

Su escenario de ser rechazado por la competencia durante las horas de relleno es precisamente la razón por la que debe documentar la complejidad. Si documenta y justifica (con un requisito específico del cliente) el uso de cualquier patrón, entonces está cubierto. Si no puede justificar un patrón con el requisito de un cliente, entonces parece un diseño excesivo o una patrón.

Si los requisitos cambian, entonces puede justificar dejarlo debido al riesgo de que pueda romper el código (o la cantidad de trabajo para eliminar quirúrgicamente el patrón).


Creo que es bueno distinguir entre la complejidad accidental y la complejidad esencial , ya que los patrones a menudo involucran a ambos.

Es decir, su requisito de admitir algoritmos variables para decidir aumentos es una complejidad esencial (parte del problema a resolver). El mantenimiento de su código se facilita con el patrón de la Estrategia, pero la alternativa codificada si / entonces a la Estrategia seguirá funcionando. He realizado ejercicios en mis cursos de maestría donde los estudiantes encuentran oportunidades para aplicar la Estrategia en proyectos de código abierto. La complejidad no es necesariamente mejor / peor cuando se aplica la Estrategia (porque es una complejidad esencial ). A veces puede ser aún más difícil entender la Estrategia, porque el código se divide en varias clases con polimorfismo, en lugar de un gran bloque if / then / else.

Idealmente, un patrón funciona cuando los beneficios que proporciona superan el costo de sus inconvenientes. Nuevamente, cuantificar estas cosas es difícil. A menudo, un patrón hace feliz al desarrollador (no solo porque hace que sea más fácil agregar una nueva estrategia de aumento, sino que también le da al desarrollador la oportunidad de saber que se aplicó un patrón). Es difícil mostrar a los clientes cómo los beneficia.

Al cliente no le importa ni comprende los detalles. En el caso de que el nuevo propietario aplique KISS en sus procesos, es ella la que reduce la complejidad esencial , lo que también debería tener un impacto en la solución de software.

Fuhrmanator
fuente