¿Qué son la complejidad esencial y accidental?

Reduzcamos el alcance de la respuesta a la complejidad esencial y accidental en el dominio de la ingeniería de software, porque eso es lo que implica la etiqueta “Computer Science”.

¿Qué es la complejidad de una pieza de software?

Incluso si el término complejidad se puede interpretar de manera muy amplia en general, en el contexto de la ingeniería / programación de software, se denomina principalmente una combinación de las dos propiedades siguientes:

  1. Capacidad para comprender y mantener una pieza de código o una parte del sistema de software después de que se haya creado.
  2. Complejidad del algoritmo Big-O [1]: esta es la capacidad de un algoritmo para escalar mientras el tamaño de entrada está creciendo. Se aplica principalmente al tiempo de procesamiento, pero también se utiliza para el espacio utilizado (por ejemplo, en la memoria o en el disco) por un algoritmo.

Expectativa de complejidad

Muy a menudo, al echar un vistazo rápido al complejo código, un profesional experimentado puede decir si la complejidad que está observando es esencial o accidental. En palabras simples sin conocer los detalles exactos de implementación, puede estimar si el mismo problema puede resolverse con un código menos complejo o no.

Causas típicas:

  1. Cuando un desarrollador no está familiarizado con la gama completa de capacidades del marco o la tecnología utilizada, a menudo tiende a elegir una técnica y reutilizarla para todos los fines, incluso si hay mejores alternativas (síndrome de martillo y clavo [2]). Probablemente lo más problemático es la ignorancia de algoritmos y estructuras de datos bien conocidos. Por ejemplo, muchos desarrolladores de Java / c # usan en exceso la estructura de datos de la Lista, incluso si un iterador, Stack o Array podría ser suficiente. Un ingeniero experimentado notará rápidamente que no hay operaciones de eliminación, por lo que el uso de la lista obviamente es demasiado grande.
  2. Un desarrollador tiende a generalizar en exceso una tarea . Un amigo mío le pidió a un programador que escribiera un programa para imprimir nombres de los 10 clientes más rentables. Al programador se le ocurrió una aplicación con una interfaz de usuario compleja que ofrece infinitas posibilidades de consultar los datos del cliente. Los programadores a menudo nos olvidamos de hacer lo mínimo necesario, tratando de predecir posibles requisitos futuros.
  3. Una vez escrito y funcionando, un fragmento de código puede optimizarse y simplificarse para reducir la complejidad. Sin embargo, muchos programadores tienden a no tocar un sistema en ejecución debido a la falta de tiempo y pruebas . La situación empeora aún más cuando los errores se corrigen bajo presión de tiempo y sin tener pruebas en su lugar. Los desarrolladores intentan hacer cambios con el mínimo impacto posible, sin revisar y optimizar todo el código. Como resultado, la complejidad crece innecesariamente con el tiempo.

Notas al pie

[1] Una guía para principiantes sobre la notación Big O

[2] Ley del instrumento – Wikipedia

Los términos Complejidad esencial y Complejidad accidental son acuñados por Ben Moseley y Peter Marks en su artículo Out of the Tarpit [1]. Su significado en las palabras Essential y Accidental se extraen de No Silver Bullet de Fred Brook [2].

Para resumir, los términos se definen como tales:

  • La Complejidad Esencial es la complejidad inherente al problema. Es una complejidad relacionada con el problema y no se puede eliminar.
  • La Complejidad Accidental es la complejidad no relacionada con el problema. Ben Mosely y Peter Marks lo describen como un “accidente”. Es una complejidad por culpa del desarrollador y resulta que está allí.

¿Qué es la complejidad del software?

Moseley, Marks y Brooks no definen la complejidad muy bien. Parece que solo están de acuerdo en que la complejidad es algo que hace que el software sea difícil de entender y difícil de programar correctamente.

Para la definición de complejidad, me gusta mucho la definición dada por Rich Hickey en Simple Made Easy [3]. La complejidad es básicamente un enredo de componentes, ideas, etc. A mis ojos, las definiciones de complejidad esencial y accidental se convierten en:

  • La complejidad esencial es el enredo / combinación de componentes / ideas en el software necesario para resolver el problema en cuestión. No se puede evitar.
  • La complejidad accidental es el enredo de componentes / ideas que no es necesario para resolver el problema. Esta complejidad es accidental porque alguien probablemente no pensó lo suficiente antes de unir innecesariamente las cosas. Como resultado, el software es más difícil de entender de lo que debería ser.

Notas al pie

[1] http://shaffner.us/cs/papers/tar

[2] http://worrydream.com/refs/Brook

[3] Simple hecho fácil

La complejidad accidental son complicaciones de las que puede deshacerse con un mejor diseño. La complejidad esencial son las complicaciones con las que estás atrapado.

Si no recuerdo mal, Fred Brooks acuñó esa terminología en The Mythical Man-Month.

Una vez más, si recuerdo correctamente (después de haber leído el libro hace 20 años), la complejidad esencial es la complejidad inherente al problema, mientras que la complejidad accidental es la complejidad introducida como parte de la solución.