La complejidad de la programación (o complejidad del software ) es un término que incluye propiedades del software que afectan las interacciones internas. Varios comentaristas distinguen entre los términos "complejo" y "complicado". Complicado implica ser difícil de entender, pero en última instancia cognoscible. Complejo, por el contrario, describe las interacciones entre entidades. A medida que aumenta el número de entidades, el número de interacciones entre ellas aumenta exponencialmente, haciendo 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, aumentando así el riesgo de introducir defectos al cambiar el software. 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 su mantenibilidad ha sido explorada extensamente por el profesor Manny Lehman , quien desarrolló sus Leyes de la evolución del software . Él y su coautor Les Belady exploraron numerosas métricas de software que podrían usarse para medir el estado del software y finalmente concluyeron que la única solución práctica es utilizar modelos de complejidad deterministas. [1]
Tipos
La complejidad de un programa existente determina la complejidad de cambiar el programa. La complejidad del problema se puede dividir en dos categorías: [2]
- La complejidad accidental se relaciona con las dificultades que enfrenta un programador debido a las herramientas de ingeniería de software. Seleccionar un mejor conjunto de herramientas o un lenguaje de programación de nivel superior puede reducirlo. La complejidad accidental a menudo resulta de no utilizar el dominio para enmarcar la forma de la solución. [ cita necesaria ] El diseño basado en dominios puede ayudar a minimizar la complejidad accidental.
- La complejidad esencial está causada por las características del problema a resolver y no se puede reducir.
Medidas
Se han propuesto varias 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
- La métrica de complejidad ciclomática de McCabe
- Métricas de la ciencia del software de Halstead
- Henry y Kafura introdujeron las "Métricas de estructura de software basadas en el flujo de información" en 1981, [3] que miden la complejidad en función de la "entrada" y la "salida". Definen el fan-in 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 se define como la cantidad de flujos locales que salen de ese procedimiento más la cantidad de estructuras de datos que actualiza el procedimiento. Los flujos locales se relacionan con los datos pasados hacia y desde procedimientos que llaman o son llamados por el procedimiento en cuestión. El valor de complejidad de Henry y Kafura se define como "la duración del procedimiento multiplicada por el cuadrado de la entrada multiplicada por la salida" (Longitud × (entrada × salida)²).
- Chidamber y Kemerer introdujeron "Un conjunto de métricas para el diseño orientado a objetos" en 1994, [4] centrándose en métricas para código orientado a objetos. Introducen seis métricas de complejidad de OO: (1) métodos ponderados por clase; (2) acoplamiento entre clases de objetos; (3) respuesta para una clase; (4) número de hijos; (5) profundidad del árbol de herencia; y (6) falta de cohesión de los métodos.
Se pueden utilizar varias otras métricas para medir la complejidad de la programación:
- Complejidad de ramificación (métrica de necesidad)
- Complejidad del acceso a datos (métrica de tarjeta)
- Complejidad de los datos (métrica de Chapin)
- Complejidad del flujo de datos (métrica de Elshof)
- Complejidad decisional (Métrica McClure)
- Complejidad de la ruta (métrica Bang)
La Ley de Tesler es un adagio en la interacción entre humanos y computadoras que establece que cada aplicación tiene una complejidad inherente que no se puede eliminar ni ocultar.
Métricas de Chidamber y Kemerer
Chidamber y Kemerer [4] propusieron un conjunto de métricas de complejidad de programación ampliamente utilizadas en mediciones y artículos académicos: 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, que se describen a continuación:
- Métodos ponderados por clase ("WMC")
![{\displaystyle WMC=\sum _ {i=1}^{n}c_ {i}}](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)
- n es el número de métodos en la clase
es la complejidad del método
- Acoplamiento entre clases de objetos ("CBO")
- número de otra clase que está acoplada (usando o siendo utilizada)
- Respuesta para una clase ("RFC")
dónde![{\displaystyle RS=\{M\}\cup _{todos\ i}\{R_{i}\}}](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)
es un conjunto de métodos llamados por el método i
es el conjunto de métodos de la clase
- Número de niños ("NOC")
- suma de todas las clases que heredan esta clase o un descendiente de ella
- Profundidad del árbol de herencia ("DIT")
- profundidad máxima del árbol de herencia para esta clase
- Falta de cohesión de métodos ("LCOM")
- Mide la intersección de los atributos utilizados en común por los métodos de clase.
![{\displaystyle LCOM={\begin{casos}|P|-|Q|,&{\text{if }}|P|>|Q|\\0,&{\text{de lo contrario }}\end{casos }}}](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)
- Dónde
![{\displaystyle P=\{(I_{i},I_{j})|I_{i}\cap I_{j}=\emptyset \}}](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)
- Y
![{\displaystyle Q=\{(I_{i},I_{j})|I_{i}\cap I_{j}\neq \emptyset \}}](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)
- With es el conjunto de atributos (variables de instancia) a los que se accede (leído o escrito) por el -ésimo método de la clase
![{\ Displaystyle I_ {i}}](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)
![{\displaystyle i}](data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)
Ver también
Referencias
- ^ MM Lehmam LA Belady; Evolución del programa: procesos de cambio de software 1985
- ^ En ingeniería de software, un problema se puede dividir en su complejidad accidental y esencial [1].
- ^ Enrique, S.; Kafura, D. IEEE Transactions on Software Engineering Volumen SE-7, Número 5, septiembre de 1981 Página(s): 510 - 518
- ^ ab Chidamber, SR; Kemerer, CF IEEE Transactions on Software Engineering Volumen 20, Número 6, junio de 1994 Página(s):476 - 493