La complejidad de la programación (o la complejidad del software) es un término que incluye muchas propiedades de una pieza de software, todas las cuales afectan las interacciones internas. Según varios comentaristas, existe una distinción entre los términos complejo y complicado. Complicado implica ser difícil de entender pero con tiempo y esfuerzo, finalmente cognoscible. Complejo, por otro lado, describe las interacciones entre varias entidades. A medida que aumenta el número de entidades, el número de interacciones entre ellas aumentaría exponencialmente y llegaría a un punto en el que sería imposible conocerlas y comprenderlas todas. De manera similar, los niveles más altos de complejidad en el software aumentan el riesgo de interferir involuntariamente con las interacciones y, por lo tanto, aumentan las posibilidades de introducir defectos al realizar cambios. En casos más extremos,puede hacer que la modificación del software sea prácticamente imposible. La idea de vincular la complejidad del software con la capacidad de mantenimiento del software ha sido explorada ampliamente porProfesor Manny Lehman , quien desarrolló sus Leyes de la evolución del software a partir de su investigación. Él y su coautor Les Belady exploraron numerosas métricas de software posibles en su libro frecuentemente citado, [1] que podrían usarse para medir el estado del software, y finalmente llegaron a la conclusión de que la única solución práctica sería usar una que utiliza modelos de complejidad determinista.
Se han propuesto muchas medidas de complejidad del software. Muchos de ellos, aunque ofrecen una buena representación de la complejidad, no se prestan a una medición fácil. Algunas de las métricas más utilizadas son
Henry y Kafura introdujeron Métricas de estructura de software basadas en el flujo de información en 1981 [2], que mide la complejidad como una función de abanico y abanico. Definen el abanico de un procedimiento como el número de flujos locales en ese procedimiento más el número de estructuras de datos de las que ese procedimiento recupera información. La distribución en abanico se define como el número de flujos locales que salen de ese procedimiento más el número de estructuras de datos que actualiza el procedimiento. Los flujos locales se relacionan con los datos que se pasan hacia y desde los procedimientos que llaman o son llamados por el procedimiento en cuestión. El valor de complejidad de Henry y Kafura se define como "la longitud del procedimiento multiplicada por el cuadrado del abanico de entrada multiplicado por el abanico de salida" (Longitud × (abanico de entrada × abanico de salida) ²).
Chidamber y Kemerer introdujeron una suite de métricas para diseño orientado a objetos [3] en 1994, centrándose, como sugiere el título, en métricas específicamente para código orientado a objetos. Introducen seis métricas de complejidad OO; métodos ponderados por clase, acoplamiento entre clases de objetos, respuesta para una clase, número de hijos, profundidad del árbol de herencia y falta de cohesión de métodos
Hay varias otras métricas que se pueden usar para medir la complejidad de la programación:
Complejidad de ramificación (métrica de Sneed)
Complejidad del acceso a los datos (Card Metric)
Complejidad de los datos (métrica de Chapin)
Complejidad del flujo de datos (métrica de Elshof)
Asociada y dependiente de la complejidad de un programa existente, está la complejidad asociada con el cambio de programa. La complejidad de un problema se puede dividir en dos partes: [4]
Complejidad accidental: se relaciona con las dificultades que enfrenta un programador debido a las herramientas de ingeniería de software elegidas. Un conjunto de herramientas más adecuado o un lenguaje de programación de más alto nivel pueden reducirlo. La complejidad accidental es a menudo también una consecuencia de la falta de uso del dominio para enmarcar la forma de la solución, es decir, el código. [ cita requerida ] Una práctica que puede ayudar a evitar la complejidad accidental es el diseño impulsado por dominios .
Complejidad esencial: está provocada por las características del problema a resolver y no se puede reducir.
Chidamber y Kemerer [3] propusieron un conjunto de métricas de complejidad de programación, ampliamente utilizadas en muchas mediciones y artículos académicos. Son WMC, CBO, RFC, NOC, DIT y LCOM, que se describen a continuación:
WMC - métodos ponderados por clase
n es el número de métodos en la clase
es la complejidad del método
CBO - acoplamiento entre clases de objetos
número de otra clase que está acoplada (en uso o en uso)
RFC - respuesta para una clase
dónde
es un conjunto de métodos llamados por el método i
es el conjunto de métodos en la clase
NOC - número de niños
suma de todas las clases que heredan esta clase o un descendiente de ella
DIT - profundidad del árbol de herencia
profundidad máxima del árbol de herencia para esta clase
LCOM- falta de cohesión de métodos
Mide la intersección de los atributos usados en común por los métodos de clase.
Dónde
Y
Con es el conjunto de atributos (variables de instancia) al que se accede (se lee o se escribe) mediante el método -th de la clase