"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > La batalla interminable contra la complejidad del software

La batalla interminable contra la complejidad del software

Publicado el 2024-08-18
Navegar:131

The Never Ending Battle Against Software Complexity

¿Qué es la complejidad?

Recientemente, terminé de leer "Una filosofía del diseño de software" y, en el segundo capítulo, explora el tema de la complejidad del software. 

El libro "Una filosofía del diseño de software" define la complejidad de manera práctica:

"La complejidad es cualquier cosa relacionada con la estructura de un sistema de software que hace que sea difícil de entender y modificar."

En otras palabras, la complejidad puede tomar muchas formas y no necesariamente tiene nada que ver con el rendimiento, su código puede tener rendimiento y seguir siendo complejo

Me gustaría compartir algunas definiciones e ideas clave del libro en este artículo. Pero primero, imaginemos una situación común en la que probablemente ya hayas estado…


Una breve historia de terror

Vamos a sumergirnos en una historia de terror que muchos de ustedes probablemente hayan experimentado o experimentarán.

  1. Comenzó con una sencilla aplicación CRUD de gestión de tareas. El código era limpio, modular y fácil de mantener. El equipo de desarrollo estaba contento y el sistema funcionó perfectamente para los clientes iniciales.

  2. Los problemas comenzaron cuando el equipo de ventas vendió el sistema a una gran empresa, alegando que tenía integración de calendario, notificaciones por correo electrónico y un increíble generador de informes. Una vez finalizada la venta, estas características tuvieron que implementarse rápidamente.

  3. Integración de calendario: El equipo tuvo que integrarse con Google Calendar y Outlook. Diferentes desarrolladores implementaron las soluciones, lo que resultó en enfoques inconsistentes.

  4. Notificaciones por correo electrónico: Las notificaciones por correo electrónico se agregaron a continuación. Un desarrollador utilizó una biblioteca específica, mientras que otro creó una solución personalizada. Los enfoques mixtos hicieron que el código fuera confuso.

  5. Generador de informes: Para el generador de informes, los desarrolladores utilizaron varias tecnologías: archivos PDF, exportaciones de Excel y paneles interactivos. La falta de un enfoque unificado hizo que el mantenimiento fuera una pesadilla.

  6. Complejidad creciente: Cada función se desarrolló de forma aislada y rápida, lo que generó dependencias entre funciones. Los desarrolladores comenzaron a crear "soluciones rápidas" para que todo funcionara, aumentando la complejidad y el acoplamiento del sistema.

El desarrollo de software no ocurre en el vacío; En él influyen diversos factores internos y externos. Todos hemos estado, o estaremos, en una situación como esta.


El principio del fin

Entonces comenzaron los problemas:

  1. Los cambios en una parte del sistema afectaron a otras partes inesperadamente.
  2. Pequeños cambios requirieron modificaciones en muchos otros archivos, lo que dificulta las estimaciones.
  3. Mes tras mes, el código se volvió más difícil de entender y, a menudo, se solucionó mediante prueba y error.
  4. La productividad disminuyó y todos temían las tareas de mantenimiento.
  5. El inevitable llamado a "Necesitamos refactorizar".
  6. Ciertas tareas solo pueden ser manejadas por desarrolladores específicos (clásico)
  7. Con el tiempo, el software que alguna vez estuvo bellamente escrito y bien documentado se convirtió en un desastre.

Nombrar los síntomas

Está claro que ahora tenemos un sistema complejo.

Ahora "analicemos" esta complejidad para que sea más fácil identificarla y mitigarla.

Bueno, "mitigar" significa:

"Hacer menos grave, grave o doloroso; aliviar."

Creo que la complejidad suele ser inherente al código. Algunas cosas son complejas por naturaleza. Su función como desarrollador no es solo crear código que la computadora pueda ejecutar de manera eficiente, sino también crear código con el que los futuros desarrolladores (incluido usted mismo en el futuro) puedan trabajar.

“Controlar la complejidad es la esencia de la programación informática.”

- Brian Kernighan

El autor del libro mencionado afirma que la complejidad generalmente se manifiesta de tres maneras, que exploraremos aquí.

Cambiar amplificación

La amplificación del cambio ocurre cuando un cambio aparentemente simple requiere modificaciones en muchos lugares diferentes.

Por ejemplo, si el propietario del producto solicita un campo de "prioridad" o "fecha de finalización" y sus entidades están estrechamente vinculadas, ¿cuántos cambios necesitaría realizar?

Carga cognitiva

La carga cognitiva se refiere a la cantidad de conocimiento y tiempo que un desarrollador necesita para completar una tarea.

Imaginemos este escenario: un nuevo desarrollador se unió al equipo y se le asignó la tarea de corregir un error en el generador de informes. Para completar esta tarea, el desarrollador necesitaba:

  • Comprende las diferentes integraciones de calendario (Google y Outlook).
  • Comprenda los distintos enfoques de las notificaciones por correo electrónico.
  • Navegue a través del código fragmentado del generador de informes, manejando archivos PDF, Excel y paneles.
  • Integre estas diversas tecnologías y estilos para encontrar y corregir el error.

Es el escenario clásico "imposible de estimar", donde la tarea podría tomar uno u ocho puntos; es mejor tirar un D20 y responder en consecuencia.

Desconocidos Desconocidos

Las incógnitas desconocidas son cuando no sabes lo que no sabes.

Esta es la peor manifestación de complejidad porque puedes alterar cosas que no deberías, provocando que todo se rompa.

Ejemplo: Un desarrollador modificó el código de envío de correo electrónico para agregar una nueva notificación, sin saber que afectaría al generador de informes, que dependía de esa función. Esto causó importantes problemas a los clientes, lo que ejemplifica la peor forma de complejidad emergente.

Causas de la complejidad

Habiendo visto la historia de terror y los tres síntomas principales, veamos qué causa la complejidad.

1. Dependencias

Las dependencias son esenciales en el software y no se pueden eliminar por completo. Permiten que diferentes partes del sistema interactúen y funcionen juntas. Sin embargo, las dependencias, cuando no se gestionan adecuadamente, pueden aumentar significativamente la complejidad.

Definición:

Existe una dependencia cuando el código no se puede entender o modificar de forma aislada, lo que requiere consideración o modificación del código relacionado.

Tipos de Dependencias:

  • Directo: El módulo A depende directamente del módulo B.
  • Transitivo: El módulo A se basa en el módulo B, que a su vez se basa en el módulo C.
  • Cíclico: Los módulos A, B y C son interdependientes de forma circular.

2. Oscuridad

La oscuridad ocurre cuando la información importante no es obvia. Esto puede hacer que el código base sea difícil de entender, lo que genera una mayor carga cognitiva y el riesgo de incógnitas desconocidas.

Definición:

La oscuridad ocurre cuando la información importante no es obvia.

Ejemplos de oscuridad:

  • Nombres deficientes: Variables y funciones con nombres poco claros.
  • Efectos secundarios ocultos: Métodos que realizan acciones inesperadas.
  • Estado global: Uso excesivo de variables globales.
  • Herencia profunda: El comportamiento se extiende a través de muchos niveles en las jerarquías de clases.

Recuerde: la complejidad es incremental

  • La complejidad rara vez es causada por un solo "error" o una mala decisión.
  • La complejidad se acumula "lentamente" a través de malas decisiones y dependencias con el tiempo.

Debido a que es incremental, es fácil pensar: "Sólo por esta vez, no importará". Pero cuando se acumula, arreglar una o dos dependencias por sí solo no hará mucha diferencia.

“Todo es una compensación en la ingeniería de software.”
— No recuerdo el autor

Conclusión

Podría escribir muchas reglas, estrategias y marcos que probablemente ya hayas visto en Internet sobre cómo evitar la complejidad: SOLID, Design Patterns, YAGNI, KISS, etc.

Sin embargo, puedes unificarlos todos en un principio rector (como se menciona en "El programador pragmático"): "¿Lo que estoy implementando es fácil de cambiar?" Si la respuesta es no, entonces probablemente esté aumentando la complejidad.

Asegurar que su código sea fácil de cambiar simplifica el mantenimiento, reduce la carga cognitiva de los desarrolladores y hace que el sistema sea más adaptable y menos propenso a errores.

¡Gracias!

Declaración de liberación Este artículo se reproduce en: https://dev.to/juniorklawa/the-never-ending-battle-against-software-complexity-46k1?1 Si hay alguna infracción, comuníquese con [email protected] para eliminarla.
Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3