Está en la página 1de 34

EL MANTENIMIENTO DEL SISTEMA

EL SISTEMA EN PROCESO DE CAMBIO


El desarrollo del sistema está completo cuando alcanza el estadio operacional, es decir cuando los usuarios lo
están utilizando en un ambiente de producción real. Se considera como mantenimiento cualquier trabajo hecho
para cambiar un sistema después de ponerlo en operación. Muchas personas piensan en el mantenimiento de
sistemas de software al igual que lo hacen en relación al mantenimiento del hardware: prevención o reparación
de partes rotas o que no trabajen correctamente. Sin embargo, el mantenimiento del software no puede verse de
la misma manera. Ahora se verá por qué.

Una meta de la ingeniería del software es el desarrollo de técnicas que permitan definir un problema con
exactitud, diseñar un sistema como una solución, implementar un conjunto correcto y eficiente de programas, y
probar el sistema en lo concerniente a defectos. Esta meta es similar para los diseñadores del hardware: producir
un producto confiable, libre de defectos, que trabaje según la especificación. El mantenimiento del hardware en
tal sistema se concentra en el reemplazo de partes deterioradas o en el uso de técnicas que prolongan la vida del
sistema. Sin embargo, una estructura whiledo no se gasta después de 10.000 iteraciones y los puntos y comas
no se caen de los extremos de las líneas de comando. A diferencia del hardware, el software no se degrada ni
requiere mantenimiento periódico. Por lo tanto, los sistemas de software son diferentes del hardware y no es
posible aplicar con éxito las analogías con él de la forma que puede hacerse para otros aspectos de ingeniería del
software.

Tipos de sistemas:
La principal diferencia entre el hardware y los sistemas de software es que los sistemas de software se
construyen para que incorporen cambios. Salvo los casos más simples, los sistemas desarrollados son evolutivos.
Es decir, una o más de una de las características que definen un sistema cambian normalmente durante la vida
del sistema. Lehman (1980) ha descrito un modo de categorizar los programas en términos de la manera en que
pueden cambiar. Esta categorización también puede aplicarse a los sistemas. Los sistemas de software pueden
cambiar no sólo porque un cliente toma la decisión de hacer algo de una manera diferente, sino también debido
a que cambia la naturaleza del propio sistema. [[Consideremos por ejemplo, el caso de un sistema de pagos al
personal que calcula las deducciones y emite cheques de sueldo para una compañía. Este sistema es dependiente
de las leyes impositivas y de regulaciones de la ciudad, del estado o provincia y del país en que se encuentra
ubicada la compañía. Si las leyes cambian o si la compañía se traslada a otro sitio, el sistema puede requerir
modificaciones. En consecuencia, pueden requerirse cambios del sistema aun cuando haya estado trabajando
adecuadamente en el pasado.]]

Por qué algunos sistemas son más proclives al cambio que otros? En general, se puede describir un sistema en
términos de la manera en que se relaciona con el ambiente en que opera. A diferencia de los programas que se
manejan en lo abstracto, el mundo real contiene incertidumbres y conceptos que no siempre se comprenden
completamente. Cuanto más dependientes del mundo real sean los requerimientos de un sistema, más probable
es que se necesiten cambios.

 Los sistemas-S:
Algunos sistemas se definen formalmente mediante una especificación y son derivables de ella. En estos
sistemas, un problema específico se declara en términos de un conjunto completo de circunstancias a las cuales
se aplica. [[Puede solicitarse por ejemplo la construcción de un sistema para realizar la suma, la multiplicación y la
inversión de matrices, en un conjunto dado de matrices dentro de determinadas restricciones de desempeño.]]
Este es un problema completamente definido y hay una o más soluciones correctas al problema tal como está
declarado. La solución es muy conocida, por lo que el diseñador no se preocupa por la exactitud de la solución,
sino por la exactitud de la aplicación de la solución. Un sistema construido de esta manera se denomina sistema-
S. Este tipo de sistemas es estático y no admite fácilmente un cambio en el problema que le da origen.
Como se muestra en la figura 11.1 el problema resuelto por un sistema-S está relacionado con el mundo real y el
mundo real está sujeto a cambios. Sin embargo, si el mundo cambia, el resultado es un problema
completamente nuevo, que debe ser especificado.

Figura 11.1

 Los sistemas-P:

Los científicos de la computación a menudo suelen definir problemas abstractos usando el criterio de los
sistemas-S, y pueden desarrollar sistemas para resolverlos. Sin embargo, no siempre es fácil o posible describir
completamente un problema del mundo real. En muchos casos, la solución teórica a un problema existe, pero la
implementación de la solución es impráctica o imposible.

[[Consideremos como ejemplo un sistema para jugar ajedrez. Dado que las reglas del juego de
ajedrez están completamente definidas, el problema puede ser completamente especificado. En cada paso del
juego, una solución podría involucrar el cálculo de todos los posibles movimientos y sus consecuencias, para
determinar el próximo movimiento mejor. Sin embargo, usando la tecnología actual, implementar
completamente tal solución es imposible. El número de movimientos es demasiado grande para ser evaluado en
una cantidad práctica de tiempo. Por lo tanto, conviene desarrollar una solución aproximada que a los fines de la
construcción y la utilización es más práctica.]]

Para desarrollar esta solución, se describe el problema de una manera abstracta y entonces se escribe la
especificación de requerimientos del sistema desde un punto de vista abstracto. Un sistema desarrollado de esta
manera se denomina sistema-P, porque está basado en una abstracción práctica del problema en lugar de una
especificación completamente definida. Como se muestra en la figura 11.2, un sistema-P es más dinámico que un
sistema-S. La solución produce información que se compara con el problema; si la información es de algún modo
inadecuada, puede cambiarse la abstracción del problema y modificarse los requerimientos, para intentar hacer
más realista la solución resultante.

Así, en un sistema-P, los requerimientos están basados en la aproximación. La solución depende en parte de la
interpretación del analista que genera los requerimientos. Si bien puede existir una solución exacta, la solución
producida por un sistema-P está templada por el ambiente en que debe producirse. En un sistema-S, la solución
es aceptable si las características técnicas son correctas. Sin embargo, en un sistema-P, la solución es aceptable si
los resultados tienen sentido en el mundo en el que el problema está embebido.

Muchas cosas pueden cambiar en un sistema-P. Cuando la Información


de salida se compara con el problema real, la abstracción puede cambiar
o los requerimientos pueden necesitar algún tipo de modificación, y la
implementación puede verse afectada en concordancia con tales
cambios. El sistema que resulta de los cambios no puede ser considerado
como una nueva solución a un nuevo problema. Más bien, es una
modificación de una solución anterior para encontrar un mejor ajuste al
problema existente.

 Los sistemas-E:

En los casos de los sistemas S y P considerados, la situación del mundo real permanece estable. Sin embargo, una
tercera clase de sistemas incorpora naturaleza cambiante del propio mundo real. Un sistema-E es un sistema que
está incorporado en el mundo real y cambia como el mundo lo hace. La solución está basada en un modelo de los
procesos abstractos involucrados. En consecuencia, el sistema es una parte integral del mundo que modela.

[[Es el caso de un sistema que predice la salud económica de un país, que está basado en un modelo sobre el
funcionamiento económico. Los cambios ocurren en el mundo en que el problema está inmerso. A su vez, la
economía no se entiende completamente, de modo que el modelo cambia a medida que cambia la comprensión
de lo económico.]] En definitiva, la solución cambia cuando cambia el modelo abstracto.
La Figura 1 1.3 ilustra la mutabilidad de un sistema-E y su dependencia del contexto de su mundo real.
Considerando que los sistemas-S son de cambio improbable y que los sistemas-P están sujetos a cambio
incremental, es probable que los sistemas-E experimenten el cambio casi constante. Es más, el éxito de un
sistema-E depende completamente de la evaluación del desempeño del sistema por parte del cliente. Dado que
un problema encarado por un sistema-E no puede especificarse completamente, el sistema debe juzgarse
solamente por su comportamiento bajo condiciones operativas
reales.

Estas categorías presentan los elementos del sistema sujetos al


cambio. Cuanto mayor sea el número de elementos proclives al
cambio, más probable es la necesidad de mantenimiento del
sistema. En particular, dado que el problema que origina un
sistema-E puede cambiar, la solución del sistema-E
experimentará probablemente un perfeccionamiento constante.
Los cambios durante el ciclo de vida del sistema:
Examinando el sistema a la luz de su categoría (S, P o E), es posible ver dónde puede producirse el cambio
durante el desarrollo y también cómo se verá afectado por el cambio. Por su naturaleza, la problemática de un
sistema-S está complemente definida y es improbable que cambie. Se puede resolver un problema similar
modificando el sistema-S, pero el resultado es un problema completamente nuevo con una solución. Que un
sistema-S funcione de manera inaceptable se debe normalmente a que trata el problema equivocado. Ante esta
situación, se redefine el problema y se genera una nueva descripción; luego se desarrolla una nueva solución, en
lugar de modificar el sistema anterior.

Un sistema-P es una solución aproximada a un problema y puede requerir cambios a medida que se identifican
las discrepancias y omisiones. De hecho, cuando se compara y contrasta la información producida por el sistema
con la situación real que está siendo modelada, se puede cambiar el sistema-P, para asegurar que es económico y
efectivo.

Para un sistema-P, un modelo aproxima una solución del problema declarado, de modo que la modificación
puede ocurrir durante todas las fases de desarrollo. Primero, la abstracción puede cambiar. En otros términos, se
altera la descripción abstracta, y entonces cambia en concordancia la especificación de requerimientos. Luego, se
modifica el diseño del sistema, se rehace la implementación y se prueba para incorporar los cambios. Finalmente,
se modifica el sistema aproximado y la documentación del programa y hasta es posible que se requiera un nuevo
entrenamiento.
Los sistemas-E utilizan abstracciones y modelos para aproximar una situación, por lo que están sujetos por lo
menos a los tipos de cambios que puede experimentar un sistema-P. De hecho, su naturaleza es más inconstante
porque el problema también puede cambiar. Estando inmersos en actividades cambiantes, los sistemas-E pueden
requerir que las características se construyan en el propio sistema para acomodar el cambio.

En la Tabla 11.1 se presentan ejemplos de los cambios que suelen afectar a sistemas de cualquier tipo. Una
modificación de requerimientos durante la actividad de análisis de los requerimientos puede dar lugar a un
cambio en la especificación. Una modificación al diseño técnico puede requerir un cambio en el diseño del
sistema y quizás en los requerimientos originales. Por lo tanto, un cambio en cualquier estadio del desarrollo
también puede afectar los resultados de los anteriores, así como las fases subsiguientes.
[[Los principios de la ingeniería del software sugeridos para el desarrollo del sistema también hacen más fácil la
instrumentación de los cambios durante el mantenimiento. Por ejemplo, si el diseño y los componentes del
código están modularizados y existen referencias cruzadas de los componentes con los requerimientos, se puede
rastrear fácilmente un cambio desde los requerimientos a los componentes afectados y a las pruebas que deban
realizarse nuevamente. De manera similar, si se produce una falla, se puede identificar el componente que
contiene las causas y entonces hacer las correcciones en todos los niveles (el diseño, el código y la prueba) en
lugar de hacerlo simplemente en el código. En consecuencia, los principios de la ingeniería del software no sólo
contribuyen al buen diseño y al código correcto, sino también a la aptitud para hacer cambios rápida y
fácilmente.]]

El lapso de vida de un sistema:


Quienes intentan construir un producto mantenible, como ingenieros del software se deben formular a sí mismos
una primera pregunta: si es posible construir un sistema correcto al primer intento. En otros términos, si se usan
componentes muy cohesivos, con mínimo acoplamiento, si la documentación es completa y está actualizada, y si
el sistema completo tiene cruce de referencias, ¿igualmente se necesitará una fase de mantenimiento?
Lamentablemente, la respuesta es sí. Las razones residen en la naturaleza misma de los sistemas. Como se ha
visto, no hay manera alguna de garantizar que los sistemas de tipo E o P no requerirán cambio. De hecho, es
necesario asumir que habrá cambios y por lo tanto construirlos para que puedan realizarse fácilmente.

Entonces, la próxima pregunta debe ser: ¿Cuánto cambio puede esperarse? De nuevo, la respuesta depende de la
naturaleza del sistema. Los sistemas-S tendrán poco o ningún cambio. Los sistemas-P tendrán mucho más y es
probable que los sistemas-E cambien continuamente. Por esta razón, muchos ingenieros del software prefieren
llamarle fase evolutiva a la etapa del desarrollo dedicada al mantenimiento. Se habla de sistemas heredados,
haciendo referencia a los que fueron construidos con anterioridad, cuando las necesidades y el ambiente eran
totalmente diferentes. Como se verá luego, estos sistemas heredados deben ser evaluados para contribuir a que
evolucionen a medida que lo hacen la tecnología y las necesidades de negocio. En cierto punto, es posible tomar
la decisión de reemplazar un sistema heredado por uno completamente nuevo o simplemente retirarlo porque ya
no resulta necesario.

Tiempo de desarrollo versus tiempo de mantenimiento: Se pueden observar los tiempos de desarrollo y de
mantenimiento de otros proyectos para formarse una idea de cuán prolongada puede llegar a ser la fase
evolutiva de un sistema. Según Parikh y Zveginczov (1983), el proyecto de desarrollo típico toma entre uno y dos
años, pero requiere unos cinco o seis años adicionales de tiempo de mantenimiento. En lo concerniente al
esfuerzo, más de la mitad de los recursos de programación de un proyecto se gastan en el mantenimiento. Un
estudio realizado por Fjeldstad y Hamlen (1979) reporta una partición similar; 25 organizaciones dedicadas al
procesamiento de datos informaron que, en promedio, el 39% de esfuerzo se aplica al desarrollo y el 61% se
consume en mantenimiento (la corrección, modificación y soporte del usuario). Recientes estudios informan
sobre resultados similares y muchos desarrolladores cuentan con la regla 80-20: un 20% del esfuerzo está en el
desarrollo y 80% se aplica al mantenimiento.

Evolución del sistema versus declinación del sistema: Cuando un sistema requiere cambios significativos e
incesantes, cabe decidir si no es mejor desechar el viejo sistema y construir uno nuevo para reemplazarlo. Para
tomar esa determinación, es necesario realizar varias preguntas:
 ¿El costo de mantenimiento es demasiado alto?
 ¿La confiabilidad del sistema es inaceptable?
 ¿El sistema ya no se puede adaptar a un cambio extenso y dentro de un lapso razonable de tiempo?
 ¿El desempeño del sistema todavía supera las restricciones prescritas?
 ¿Las funciones del sistema son de utilidad limitada?
 ¿Hay otros sistemas que puedan hacer el mismo trabajo mejor, más rápido o más barato?
 ¿El costo de mantener el hardware es lo bastante grande como para justificar su reemplazo con hardware
más barato y más nuevo?

Una respuesta positiva a algunas o todas estas preguntas puede significar que es tiempo de considerar un nuevo
sistema para reemplazar al antiguo. El conjunto completo de casos asociados con el desarrollo y el
mantenimiento del sistema, desde su creación hasta que queda definitivamente fuera de uso, se denomina costo
del ciclo de vida. A menudo, la decisión de mantener, reconstruir o reemplazar se toma basándose en una
comparación de costos del ciclo de vida para el viejo sistema, el revisado y el nuevo.

Leyes de la evolución del software: La comprensión de lo que les sucede a los sistemas con el tiempo sirve para
respaldar las decisiones de mantenimiento. Interesan principalmente los cambios que afectan el tamaño, la
complejidad, los recursos y la facilidad de mantenimiento. Se puede aprender mucho sobre las tendencias
evolutivas examinando grandes sistemas para ver cómo han cambiado. [[Por ejemplo, en el Cuadro Destacado
11.1 se describe la evolución de un sistema de gran tamaño en la compañía Bell Atlantic.]]

A lo largo de su carrera, Lehman ha observado el comportamiento de sistemas mientras evolucionan. Ha


restituido sus resultados en cinco leyes de evolución del programa (Lehman 1980):

1) Continuidad del cambio. Un programa que se utiliza experimenta el cambio incesante o se hace
progresivamente menos útil. El cambio o el proceso de decaimiento continúan hasta que resulta más
rentable reemplazar el sistema con una versión recreada.
2) Complejidad creciente. Como un programa que evoluciona cambia continuamente, su estructura se
deteriora. Reflejando esta circunstancia, su complejidad aumenta a menos que se haga el trabajo para
mantenerla o reducirla.
3) Ley fundamental de la evolución de un programa. La evolución de un programa está sujeta a una dinámica
que hace que el proceso de programación, y por ende las medidas del proyecto global y los atributos del
sistema, se autorregulen con las tendencias y las invariancias determinables estadísticamente.
4) Conservación de la estabilidad orgánica (proporción del trabajo invariante). Durante la vida activa de un
programa, la proporción de actividad global en un proyecto de programación es estadísticamente
invariante.
5) Conservación de familiaridad (complejidad percibida). Durante la vida activa de un programa, el contenido
de la emisión (cambios, adiciones, eliminaciones) de las ediciones sucesivas de un programa que
evoluciona resulta invariante estadísticamente.

La primera ley dice que los grandes sistemas nunca están completos; es decir, continúan evolucionando. Los
sistemas crecen cuando se agregan más características, se aplican más restricciones, interactúan con otros
sistemas, soportan un número mayor de usuarios, y así sucesivamente. También cambian porque sus ambientes
cambian: se transportan a otras plataformas o se vuelven a escribir en alguno de los nuevos lenguajes.
La segunda ley, dice que cuando los grandes sistemas evolucionan, se acrecienta su complejidad a menos que se
realicen las acciones para reducirla. Muchas veces, este aumento en la complejidad se produce porque se hacen
parches apresurados para subsanar problemas. Simplemente no es posible tomarse el tiempo para mantener la
elegancia de un diseño o la consistencia del enfoque a través del código.

De acuerdo con la tercera ley, los sistemas de software exhiben comportamientos regulares y tendencias que se
pueden medir y predecir. De hecho, muchos ingenieros del software e investigadores consagran su estudio a
encontrar estas "verdades universales" del desarrollo y mantenimiento del software.

La cuarta ley establece que no hay fluctuaciones abruptas o amplias en los atributos organizacionales, como la
productividad. Es decir, en cierto punto, los recursos y la salida alcanzan un nivel óptimo y el agregado de más
recursos no cambia significativamente el rendimiento.

De manera similar, la quinta ley dice que después de un cierto tiempo, los efectos de las ediciones subsiguientes
representan una diferencia muy pequeña en la funcionalidad del sistema global.

LA NATURALEZA DEL MANTENIMIENTO


Cuando se desarrollan sistemas, el enfoque principal está puesto en la producción de código que implemente los
requerimientos y trabaje correctamente. En cada estadio del desarrollo, el equipo toma continuamente como
referencia para su trabajo lo producido en las fases más tempranas. Los componentes del diseño se vinculan con
la especificación de requerimientos, los componentes del código se referencian en forma cruzada y se repasan
para que concuerden efectivamente con el diseño, y las pruebas están basadas en averiguar si las funciones y
restricciones están trabajando según los requerimientos y el diseño. Por lo tanto, el desarrollo involucra la
observación cuidadosa y controlada de las etapas anteriores de diseño.

El mantenimiento es diferente. Quienes hacen mantenimiento, miran hacia atrás los productos de desarrollo,
pero también al presente estableciendo una relación activa con los usuarios y operadores para averiguar cuán
satisfechos están con la manera en que trabaja el sistema. También miran hacia adelante, para anticiparse a las
cosas que podrían salir mal, tener en cuenta los cambios funcionales motivados por una necesidad comercial
cambiante, y para considerar cambios del sistema que deriven de cambios en el hardware, el software o las
interfaces. En consecuencia, el mantenimiento tiene un alcance más amplio, con más para rastrear y controlar. A
continuación se examinan las actividades necesarias para mantener un sistema ejecutando sin complicaciones, y
se identifica a quienes las llevan a cabo.

Actividades y roles del mantenimiento:


Las actividades del mantenimiento son similares a aquéllas del desarrollo: análisis de los requerimientos,
evaluación del diseño del sistema y del programa, elaboración y revisión del código, comprobación de los
cambios y puesta al día de la documentación. Por lo tanto, las personas que realizan el mantenimiento (analistas,
programadores y diseñadores) tienen roles similares. Sin embargo, dado que los cambios requieren a menudo un
conocimiento íntimo de la estructura y volumen del código, los programadores juegan un papel mucho más
representativo en el mantenimiento que el que se les asigna en el desarrollo.

El mantenimiento enfoca simultáneamente cuatro aspectos mayores de la evolución del sistema:

1) Mantener el control sobre las funciones diarias del sistema.


2) Mantener el control sobre las modificaciones del sistema.
3) Perfeccionar las funciones aceptables existentes.
4) Impedir que el desempeño del sistema se degrade a niveles inaceptables.

1) Mantenimiento correctivo. Para controlar el funcionamiento diario del sistema, quienes integran el equipo
de mantenimiento responden a problemas que son resultados de los defectos. El tratamiento de estos
problemas se conoce como mantenimiento correctivo. A medida que ocurren las fallas, se ponen a
consideración del equipo; se encuentra la causa de la falla y se hacen las correcciones y cambios a los
requerimientos, el diseño, el código, sesiones de prueba y documentación según sea necesario. A
menudo, la reparación inicial es temporaria: como para mantener al sistema funcionando, pero no el
arreglo óptimo. Los cambios de largo alcance pueden llevarse
a cabo después, para corregir los problemas más generales con el diseño o el código.
[[Es el caso en que un usuario reclama por un informe que presenta demasiadas líneas impresas en una
página. Los programadores determinan que el problema es resultado de un defecto de diseño del
controlador de la impresora. Como reparación de emergencia, un miembro del equipo le muestra al
usuario cómo restablecer el número de líneas por página, colocando un parámetro en el menú del
informe antes de imprimir. En el futuro, el equipo rediseña, recodifica y prueba de nuevo el controlador
de la impresora, para que funcione correctamente sin la intervención del usuario.]]

2) Mantenimiento adaptativo. A veces, la introducción de un cambio en una porción del sistema requiere la
realización de cambios en otras de sus partes. El mantenimiento adaptativo es la aplicación de estos
cambios secundarios. [[Supongamos por ejemplo que el sistema existente de gestión de una base de
datos, que es parte de un sistema hardware y software mayor, se actualiza a una nueva versión. Durante
el proceso los programadores encuentran que las rutinas de acceso al disco requieren un parámetro
adicional. Los cambios adaptativos que se hacen para agregar el parámetro extra no corrigen los defectos;
meramente permiten adaptar el sistema a medida que evoluciona.]]
[[De manera similar, supongamos un compilador que se refuerza adicionándole un depurador. Será
necesario alterar los menús, los iconos, las definiciones de las teclas de función para permitirles a los
usuarios seleccionar la opción de depuración.]]
El mantenimiento adaptativo también puede realizarse debido a cambios en el hardware o en el
ambiente. [[Si un sistema originalmente diseñado para trabajar en un ambiente seco y estable se
selecciona para utilizarlo en un tanque o en un submarino, el sistema debe adaptarse para adaptarse al
movimiento, el magnetismo y la humedad.]]

3) Mantenimiento perfectivo. A medida que se realiza el mantenimiento de un sistema, se examinan los


documentos, el diseño, el código y las pruebas, buscando oportunidades para la mejora. [[Por ejemplo,
cuando se agregan nuevas funciones a un sistema, el diseño original, limpio, controlado por tablas, se
puede tornar confuso y difícil de seguir.]] Un rediseño con un enfoque basado en reglas puede reforzar el
mantenimiento futuro y hacer que en el futuro sea más fácil agregar las funciones. El mantenimiento
perfectivo implica hacer cambios para mejorar algún aspecto del sistema, incluso cuando los cambios no
son sugeridos por los defectos. Los cambios de la documentación para clarificar los puntos, el cambio de
la sesión de prueba para mejorar la cobertura de prueba, y las modificaciones del código y del diseño para
reforzar la legibilidad son todos ejemplos de mantenimiento perfectivo.
4) Mantenimiento preventivo. Similar al mantenimiento perfectivo, el mantenimiento preventivo involucra la
modificación de algún aspecto del sistema a fin de prevenir las fallas. Puede incluir la incorporación de
verificación de tipos, el perfeccionamiento del manejo de defectos o el agregado de una sentencia catch-
all en una sentencia case, para garantizar que el sistema puede manejar todas las posibilidades. Por lo
general el mantenimiento preventivo se realiza a partir del momento en que el programador o el
analizador de código encuentran un defecto real o potencial, que todavía no se ha manifestado como
falla, y encaran las acciones necesarias para corregir el defecto antes de que se produzca el daño.

Quién realiza el mantenimiento. El equipo que desarrolla un sistema no siempre es el que se encarga de
mantenerlo una vez que está en operación. A menudo se emplea un equipo de mantenimiento separado para
asegurar que el sistema se ejecuta correctamente. Existen aspectos positivos y negativos de asignar el
mantenimiento a un equipo separado. El equipo de desarrollo está familiarizado con el código, el diseño y la
filosofía detrás de él y las funciones importantes del sistema. Si los diseñadores saben que están construyendo
algo que ellos mantendrán, construirán el sistema de la manera que lo haga más fácil de mantener.

Sin embargo, los desarrolladores a veces se sienten tan seguros con su comprensión del sistema, que tienden a
no guardar la documentación actualizada. Esta falta de cuidado al escribir y revisar la documentación puede dar
como resultado la necesidad de incorporar más personas o recursos para dominar un problema. Esta situación
conduce a tener un intervalo muy largo desde el momento en que se produce el problema hasta que se
soluciona. Muchos clientes no tolerarán este retraso.

A menudo, un grupo separado de analistas, programadores y diseñadores (a veces se incluyen uno o dos
miembros del equipo de desarrollo) se designa como equipo de mantenimiento. Un equipo fresco, nuevo, puede
ser más objetivo que los diseñadores originales. A un equipo separado le puede resultar más fácil distinguir entre
cómo debe trabajar un sistema y cómo funciona realmente. Si quienes desarrollan un sistema saben que otros
trabajarán sobre su documentación, tienden a tener más cuidado sobre la documentación y los estándares de
programación.

Responsabilidades del equipo. El mantenimiento de un sistema involucra a todos los miembros del equipo. Por lo
general, los usuarios, operadores o representantes del cliente se acercan al equipo de mantenimiento con un
comentario o problema. Los analistas o programadores determinan qué parte del código son las afectadas, el
impacto en el diseño y los recursos probables (incluso tiempo y esfuerzo) para hacer los cambio necesarios. El
equipo está involucrado en muchas actividades:
1) Comprender el sistema.
2) Localizar la información en la documentación del sistema.
3) Guardar la documentación del sistema actualizado.
4) Ampliar las funciones existentes para incorporar los requerimientos nuevos o cambiantes.
5) Agregar nuevas funciones al sistema.
6) Encontrar el origen de las fallas del sistema o de los problemas.
7) Localizar y corregir los defectos.
8) Responder las preguntas acerca de la forma en que trabaja el sistema.
9) Reestructurar el diseño y los componentes del código.
10) Volver a escribir el diseño y los componentes del código.
11) Anular el diseño y los componentes del código que ya no resulten útiles.
12) Administrar los cambios al sistema a medida que se realizan.

Además, los miembros del equipo de mantenimiento trabajan con los usuarios, operadores, y clientes. En primer
término, intentan entender el problema como se expresa en el idioma del usuario. Después, el problema se
transforma en un pedido de modificación. La demanda de cambio incluye una descripción de cómo el sistema
trabaja ahora, cómo el usuario quiere que trabaje el sistema y qué modificaciones se necesitan para producir los
cambios. Una vez que el diseño o el código se modifican y se prueban, el equipo de mantenimiento vuelve a
entrenar al usuario, si es necesario. En consecuencia, el mantenimiento involucra interacción tanto con las
personas, como con el software y el hardware.

Uso del tiempo de mantenimiento. Los informes acerca de cómo distribuye su tiempo el personal de
mantenimiento entre los distintos tipos de mantenimiento varían ampliamente. [[Lientz y Swanson (1951) han
supervisado a gerentes en 487 organizaciones que procesan datos, y encontraron una distribución como la
mostrada en la Figura 11.4.]] La mayor parte del esfuerzo está dedicada al mantenimiento perfectivo y
adaptativo. Se informan distribuciones similares en estudios posteriores. Sin embargo, la distribución para una
organización dada depende de muchos factores, incluyendo si el sistema es de tipo S, P o E y de cuán
rápidamente el negocio necesite el cambio.

Figura 11.4. Distribución del esfuerzo de mantenimiento.

LOS PROBLEMAS DEL MANTENIMIENTO


Mantener un sistema es difícil. Debido a que por lo general el sistema se encuentra en operación, el equipo de
mantenimiento debe balancear la necesidad de conservarlo accesible para los usuarios con la necesidad de
efectuar el cambio. Una actualización, por ejemplo, puede requerir que el sistema quede no disponible para los
usuarios durante varias horas. Sin embargo, si el sistema es crítico para el negocio de los usuarios o para la
operación, puede resultar imposible que el usuario libere el sistema por un lapso de varias horas. Es el caso de un
sistema de respiración artificial, que no puede ser desconectado de un paciente para realizar el mantenimiento
del software. El equipo de mantenimiento debe encontrar una manera de llevar a cabo los cambios sin interferir
con la labor de los usuarios.

Problemas del personal:


Hay muchas razones organizacionales y del personal que hacen difícil el mantenimiento. El personal debe actuar
como intermediario entre el problema y su solución, arreglando y adaptando el software para asegurar que la
solución sigue el curso del problema a medida que éste cambia.
Comprensión limitada. Además de equilibrar las necesidades del usuario con las del software y las del hardware,
el equipo de mantenimiento se enfrenta con las limitaciones de la comprensión humana. Existe límite en la
rapidez con que una persona puede estudiar la documentación y extraer material relevante para el problema que
está resolviéndose. Además, normalmente se buscan más pistas que las que son realmente necesarias para
resolver un problema. Si se agregan las distracciones cotidianas de la oficina, se tiene una receta de una
productividad limitada.

Parikh y Zvegintzov (1983) informan que el 47 por ciento del esfuerzo de mantenimiento de software se consagra
a comprender el software a ser modificado. Esta cifra tan alta es entendible cuando se considera el número de
interfaces que es necesario verificar siempre que se cambia un componente. [[Por ejemplo, si un sistema tiene m
componentes y se necesita cambiar k de ellos, hay:

k*(m-k) + k“(k-l)/2

interfaces a ser evaluadas en lo relativo a impacto y exactitud (Gerlich y Denskat 1994).]] Por lo
tanto, incluso un cambio en una línea de un componente del sistema puede obligar a realizar centenares de
pruebas para garantizar que el cambio no tiene efectos directos o indirectos en otra parte del sistema.

También el entendimiento por parte de los usuarios presenta problemas. Lientz y Swanson (1981) encuentran
que más de la mitad de los problemas de los programadores dedicados al mantenimiento deriva de la falta de
habilidad o de comprensión de los usuarios. Si los usuarios no entienden cómo funciona un sistema, pueden
proporcionarles a los encargados del mantenimiento datos incompletos o engañosos al momento de informar los
efectos de un problema.

Estos resultados ilustran la importancia de tener documentación clara y completa, y del entrenamiento. El equipo
de mantenimiento también necesita buenas “habilidades personales”. El equipo de mantenimiento debe
entender cómo piensan y trabajan las personas con estilos laborales diferentes y los miembros del equipo deben
ser flexibles cuando se comunican.

Prioridades de la administración. El equipo de mantenimiento sopesa los deseos de la gerencia, del cliente y las
necesidades del sistema. Las prioridades de la gerencia a menudo sobrepasan a las técnicas; los gerentes suelen
ver el mantenimiento y el refuerzo como más importantes que la construcción de nuevas aplicaciones. En otros
términos, a veces es necesario que las compañías se concentren en el negocio habitual, en lugar de investigar
nuevas alternativas. Pero cuando los niveles de conducción animan al personal de mantenimiento a reparar un
sistema viejo, los usuarios demandan la inclusión de nuevas funciones o un nuevo sistema. De manera similar, la
prisa para conseguir un producto para comercializar puede animar a los desarrolladores y al personal de
mantenimiento a llevar a cabo un cambio rápido, poco elegante y escasamente probado, en lugar de tomar el
tiempo para seguir las buenas prácticas de la ingeniería del software. El resultado es un producto remendado que
después es difícil de entender y reparar.

La motivación. Los estudios de Lientz y Swanson (1981) indican que el 11.9% de los problemas durante el
mantenimiento son resultado de baja motivación y productividad. Una razón importante de la baja motivación
reside en la categoría secundaria que a menudo se le otorga al equipo de mantenimiento. Los programadores a
veces piensan que se requiere más habilidad para diseñar y desarrollar un sistema que para mantenerlo en
ejecución. Sin embargo, como se ha visto, los programadores de mantenimiento se ocupan de problemas que los
desarrolladores nunca ven. Quienes realizan el mantenimiento no sólo son hábiles para escribir código, sino
también para trabajar con los usuarios, anticipándose al cambio y haciendo de detectives. Se requieren gran
habilidad y perseverancia para rastrear un problema hasta su origen, entender los funcionamientos internos de
un sistema grande y para modificar la estructura, el código y la documentación. Algunos grupos rotan a los
programadores entre varios proyectos de mantenimiento y desarrollo para darles la oportunidad de desarrollarse
en una amplia gama de funciones. Esta rotación ayuda a evitar el estigma que representa la dedicación exclusiva
a la programación del mantenimiento. Sin embargo, a menudo se solicitan programadores que trabajen
concurrentemente en varios proyectos. Las demandas ejercidas sobre el tiempo de un programador derivan en
prioridades contradictorias. Durante el mantenimiento, el 8% de los problemas son el resultado de someter al
programador a un tironeo en demasiadas direcciones a la vez, lo que le impide, por lo tanto, concentrarse sobre
un problema durante el tiempo suficiente para resolverlo.

Los problemas técnicos:


Los problemas técnicos también afectan la productividad del mantenimiento. Muchas veces son un legado de lo
hecho anteriormente por desarrolladores y “mantenedores”. En otros casos son el resultado de paradigmas o
procesos particulares que se han adoptado para la aplicación.

Artefactos y paradigmas. Si la lógica del diseño no es evidente, el equipo no puede determinar fácilmente si el
diseño puede manejar los cambios propuestos. Un diseño lleno de defectos o poco flexible puede requerir
tiempo extra para entender, cambiar y probar. [[Por ejemplo, los desarrolladores pueden haber incluido un
componente para atender la entrada y la salida que sólo maneja cinta magnética; deben hacerse grandes
modificaciones para incorporar acceso a disco, porque el disco no está limitado por el acceso secuencial de la
cinta.]] De igual manera los desarrolladores pueden no haberse anticipado a los cambios; los tamaños de campos
y tablas pueden ser fijos, por lo que resultan difíciles de modificar. [[El “problema del año 2000”, derivado de
haber representado los campos de fecha utilizando sólo dos caracteres, es un buen ejemplo de casos donde las
decisiones de diseño simplistas pero de estrecha visión pueden tener un impacto significativo en el
mantenimiento.]]

También puede resultar problemático el mantenimiento de los programas orientados a objetos, porque el diseño
a menudo implica componentes con un elevado grado de interconexión mediante esquemas de herencia
complejos. Los cambios increméntales deben hacerse con gran cuidado, dado que las modificaciones pueden
producir cadenas largas de clases que ocultan a otras o que redefinen los objetos de maneras contradictorias. El
Cuadro Destacado 11.2 describe más acerca de los compromisos particulares de diseño involucrado cuando se
mantienen sistemas orientados a objetos.
En general, especificaciones de diseño inadecuadas y programas y documentación de baja calidad contabilizan
casi el 10% del esfuerzo de mantenimiento. Una cantidad similar de esfuerzo se dedica a los requerimientos del
hardware: conseguir el almacenamiento y el tiempo de proceso adecuado. Los problemas también se
incrementan cuando el hardware, el software o los datos no están disponibles en el tiempo y la forma adecuados;
todos experimentan la frustración de tener problema a resolver y no conseguir el acceso a la estación de trabajo,
o de verse obligados a marcar reiteradamente para obtener un acceso telefónico remoto. También surgen
problemas cuando el hardware, el software o los datos no son confiables.

Dificultades de la prueba. Probar puede transformarse en un verdadero problema cuando resulta difícil encontrar
el momento apropiado para hacer las pruebas. [[Es el caso de un sistema de reservas de una aerolínea que debe
estar disponible en forma permanente. Puede ser difícil convencer a los usuarios para que liberen el sistema
durante las dos horas necesarias para la prueba. Cuando un sistema realiza una función crítica como control de
tráfico aéreo o monitoreo de pacientes, puede ser imposible ponerlo fuera de servicio a fin de realizar las
pruebas.]] En estos casos, las pruebas suelen ejecutarse en sistemas duplicados; los cambios probados se
transfieren después al sistema de producción.

Además de los problemas de disponibilidad de tiempo, es posible que no existan datos de prueba buenos o
apropiados disponibles para probar los cambios realizados. [[Un sistema de predicción de terremotos, por
ejemplo, se puede modificar para ajustar las señales proporcionadas por un dispositivo sensor que está
desarrollándose. Aquí deben simularse los datos de prueba. Debido a que los científicos todavía no tienen una
comprensión completa de cómo ocurren los terremotos, puede ser difícil generar los datos de prueba exactos.]]

Pero lo más importante es que no siempre es fácil para los verificadores predecir los efectos de los cambios al
diseño o al código, y prepararse para encararlos. Esta impredicción se manifiesta sobre todo cuando diferentes
miembros del equipo de mantenimiento están trabajando al mismo tiempo en problemas diferentes. [[Si uno
hace un cambio a un componente y arregla un problema de desbordamiento de datos, mientras otro hace un
cambio al mismo componente para subsanar un problema de la interfaz, la combinación de cambios de hecho
puede causar un nuevo defecto.]]

La necesidad de compromisos:
El equipo de mantenimiento siempre está tratando de equilibrar un grupo de metas con otro. Como se ha visto,
surgen conflictos entre la disponibilidad del sistema para los usuarios y la implementación de modificaciones,
correcciones y perfeccionamientos. Dado que las fallas se producen en momentos imprevisibles, el personal de
mantenimiento está constantemente consciente de este conflicto.

Para los profesionales de la computación, toda vez que el cambio es necesario se manifiesta otro conflicto. Los
principios de la ingeniería del software compiten con la conveniencia y el costo. A menudo, un problema puede
arreglarse de una de dos maneras: una solución rápida, pero poco elegante, que funciona pero que no se
encuadra en el diseño del sistema o la estrategia de codificación, o una manera más elaborada pero elegante que
es consistente con los principios y directivas usados para generar el resto del sistema. Como se ha señalado
anteriormente, los programadores pueden verse obligados a sacrificar en parte la elegancia y los principios del
diseño porque se necesita algún cambio inmediatamente.

Cuando se establecen tales compromisos, son varios los eventos relacionados que pueden hacer más difícil el
futuro mantenimiento. En primer lugar, el usuario o el operador normalmente le presentan el reclamo al personal
de mantenimiento. Es probable que esta persona no comprenda el problema en el contexto del diseño y el
código, sino en el contexto exclusivo del funcionamiento cotidiano. Segundo, la resolución de un problema
involucra sólo la corrección inmediata de un defecto. No se hace concesión alguna para revisar el diseño del
sistema o del programa, para hacer el sistema global más entendible o efectuar los cambios de manera
consistente con el resto de los componentes. Ambos factores se combinan para presentarle al equipo de
mantenimiento una reparación rápida como única meta. El equipo se ve obligado a concentrar sus recursos en un
problema sobre que él puede tener una reducida comprensión.

El equipo debe resolver un conflicto adicional. Cuando un sistema se desarrolla para resolver un problema inicial,
sus diseñadores a veces intentan resolver problemas similares sin cambiar el diseño y el código. Tales sistemas a
menudo son lentos, porque su código de uso general debe evaluar un gran número de casos o posibilidades. Para
mejorar el rendimiento, el sistema puede incorporar componentes de propósito especial, que sacrifican la
generalidad en beneficio de la velocidad. Los componentes de propósito especial suelen ser más pequeños
porque no necesitan considerar todas las eventualidades. El sistema resultante puede cambiarse fácilmente, al
costo del tiempo que conlleva modificar o reforzar el diseño del sistema o del programa. El equipo debe ponderar
generalidad contra velocidad al decidir cómo y por qué hacer una modificación o corrección.

Otros factores que pueden afectar el enfoque adoptado por el equipo de mantenimiento incluyen:
 el tipo de falla.
 la criticidad o severidad de la falla.
 la dificultad de los cambios que se necesitan.
 el alcance de los cambios que se necesitan.
 la complejidad de los componentes que cambian.
 el número de situaciones físicas a que los cambios deben hacerse.

Todos los factores aquí mencionados indican que el personal de mantenimiento tiene una doble carga de trabajo.
En primera instancia, el equipo entiende el diseño del sistema, el código y la filosofía y estructuras de la prueba.
En un segundo paso, desarrolla una filosofía acerca de la manera en que se realizará el mantenimiento y cómo se
estructurará el sistema resultante. Equilibrando las metas de corto y largo plazo, el equipo decide cuándo
corresponde sacrificar la calidad por la velocidad.

El costo del mantenimiento:


Todos los problemas que se manifiestan al mantener un sistema contribuyen al elevado costo de mantenimiento
del software. En los años setenta, la mayoría del presupuesto de un sistema del software se gastaba en el
desarrollo. La relación entre el dinero invertido en desarrollo y el dinero destinado al mantenimiento se revirtió
durante los años ochenta, y varias estimaciones le adjudican al mantenimiento entre un 40 y un 60 por ciento del
costo del ciclo de vida completo de un sistema (es decir, desde el desarrollo, pasando por el mantenimiento hasta
que se reemplaza o se deja de utilizar). Las estimaciones actuales sugieren que los costos de mantenimiento
pueden haberse incrementado hasta alcanzar un 80% del costo del ciclo de vida de un sistema en los años 2000.

Factores que afectan el esfuerzo. Además de los problemas ya discutidos, hay muchos otros factores que
distribuyen al esfuerzo necesario para mantener un sistema. Entre estos factores pueden incluirse los siguientes:

 Tipo de aplicación. Los sistemas de tiempo real y los altamente sincronizados son más difíciles de cambiar
que aquellos donde la regulación del tiempo no es esencial para el funcionamiento apropiado. Es
necesario tener gran cuidado para asegurar que un cambio en uno de los componentes no afecta la
sincronización de otros. De manera similar los cambios a los programas con formatos de datos
rígidamente definidos pueden requerir cambios adicionales en un gran número de rutinas de acceso de
datos.
 Novedad del sistema. Cuando un sistema implementa una nueva aplicación o una nueva manera de
realizar las funciones comunes, el personal de mantenimiento no puede confiar fácilmente en su
experiencia y comprensión para encontrar y corregir los defectos. Se requiere más tiempo y esfuerzo para
entender el diseño, localizar la fuente de problemas y probar el código corregido. En muchos casos, deben
generarse datos de prueba adicionales, cuando no existen datos de prueba anteriores.
 Rotación y disponibilidad de personal de mantenimiento. Necesita un tiempo considerable para aprender
suficientemente un sistema como para entenderlo y cambiarlo. El esfuerzo de mantenimiento se resiente
si los miembros del equipo rotan en forma rutinaria entre varios grupos, si los integrantes del plantel de
mantenimiento dejan la organización para trabajar en otro proyecto o si se espera que el personal
mantenga varios productos diferentes al mismo tiempo.
 Plazo de vida del sistema. Es probable que un sistema diseñado con el propósito de durar muchos años
requiera más mantenimiento que uno cuya vida es corta. Las correcciones rápidas y la falta de cuidado
para poner al día la documentación probablemente sean aceptables para un sistema con una vida corta,
pero tales hábitos pueden ser mortíferos en un proyecto a largo plazo donde hacen que a otros miembros
del equipo les resulte más difícil realizar los cambios subsiguientes.
 Dependencia de un ambiente cambiante. Un sistema-S normalmente requiere menos mantenimiento que
un sistema-P, que a su vez necesita menos adaptación y perfeccionamiento que un sistema-E. En
particular, es probable que un sistema que depende de las características de su hardware requiera
muchos cambios si el hardware se modifica o se reemplaza.
 Características del hardware. Si los componentes de hardware o el apoyo del vendedor son poco
confiables, puede resultar más difícil rastrear un problema hasta su fuente.
 Calidad del diseño. Si el sistema no está formado por componentes independientes, altamente cohesivos,
la localización y la corrección del origen de un problema puede producir una composición de cambios que
origine efectos imprevistos sobre otros componentes.
 Calidad del código. Si el código no tiene estructura o sigue los principios pautados en su arquitectura,
puede ser difícil localizar los defectos. Además, el propio lenguaje puede hacer difícil encontrar y arreglar
defectos; los lenguajes de alto nivel a menudo refuerzan la facilidad de mantenimiento.
 Calidad de la documentación. El diseño o el código no documentados hacen casi imposible la búsqueda de
la solución a un problema. De manera similar, si la documentación es difícil de leer o incluso incorrecta, el
personal de mantenimiento puede resultar mal encaminado.
 Calidad de la prueba. Si se ejecutan las pruebas con datos incompletos o no se anticipan las repercusiones
de un cambio, las modificaciones y perfeccionamientos pueden generar otros problemas del sistema.

El modelado del esfuerzo de mantenimiento. Al igual que para el desarrollo, se desea estimar el esfuerzo que
exige mantener un sistema de software. Belady y Lehman (1972) están entre los primeros investigadores que
intentaron capturar el esfuerzo de mantenimiento en un modelo predictivo. Tuvieron en cuenta el deterioro que
con el tiempo se produce en un sistema grande. Una serie de reparaciones y perfeccionamientos normalmente
provoca la fragmentación de las actividades del sistema y, en general, el sistema se agranda con cada ronda de
reparación por mantenimiento.

En los sistemas muy grandes, los encargados del mantenimiento deben convertirse en expertos en ciertos
aspectos del sistema. Es decir, cada miembro del equipo debe especializarse en una función particular o área de
desempeño: la base de datos, la interfaz del usuario o el software de red, por ejemplo. Esta especialización a
veces deja al equipo sin generalistas; no hay una sola persona que tenga una perspectiva amplia del sistema,
sobre cómo debe funcionar y cómo se relaciona con sus requerimientos. La especialización del personal, por lo
general, deriva en un aumento exponencial de los recursos consagrados al mantenimiento. Se necesitan más
personas para acometer el sistema creciente, y deben estar disponibles las máquinas y el tiempo que les sirven
de apoyo para la realización de su trabajo. También se necesita más comunicación entre los miembros del equipo
para obtener una doble verificación sobre la compresión de cómo trabajan otros componentes o funciones del
sistema.

Al mismo tiempo, el sistema normalmente se torna más complejo como resultado de dos cosas. Primero, cuando
se corrige un defecto, la reparación misma puede introducir nuevos defectos. Segundo, cuando se hacen
correcciones, suele cambiar la estructura del sistema. Dado que muchas reparaciones se hacen con el propósito
limitado de resolver un problema particular, el acoplamiento y la cohesión de componentes, así como la
estructura de herencia de un sistema orientado a objetos, a menudo se degradan.

Belady y Lehman captan estos efectos en una ecuación:


M = p + Kc – d
donde M es el esfuerzo de mantenimiento total gastado para un sistema; p representa los esfuerzos productivos
totales: análisis, evaluación, diseño, codificación y prueba; c es la complejidad causada por la falta de
estructuración en el diseño y la documentación; la complejidad está reducida por d, que representa el grado en
que el equipo de mantenimiento está familiarizado con el software. Finalmente, K es una constante que se
determina comparando este modelo con las relaciones de esfuerzo en los proyectos reales; se la denomina
constante empírica, porque su valor depende del ambiente.

La ecuación de Belady-Lehman expresa una relación muy importante entre los factores que determinan el
esfuerzo de mantenimiento. Si un sistema se desarrolla sin los principios de la ingeniería del software, el valor de
c será alto. Además, si se hace el mantenimiento sin una comprensión del propio software, el valor de d será
bajo. El resultado es que los costos de mantenimiento aumentan exponencialmente. Por lo tanto, para
economizar en mantenimiento, el mejor enfoque consiste en construir el sistema aplicando las buenas prácticas
de la ingeniería del software y darle al personal de mantenimiento el tiempo necesario para familiarizarse con el
software.

El esfuerzo en curso y los modelos de cronograma predicen el costo de mantenimiento, usando muchos de los
mismos factores sugeridos por Belady y Lehman. Cuanto más pruebas y documentación se requieran, mayor es el
esfuerzo requerido.

Muchos de los problemas observados con respecto a la estimación durante el desarrollo se aplican igualmente a
la estimación relacionada al mantenimiento. En particular, las mejores estimaciones están basadas en las
historias completas de proyectos similares del pasado. Además, las estimaciones deben ser recalculadas a medida
que cambian los atributos del proyecto y del producto; dado que los sistemas heredados están evolucionando
continuamente, las estimaciones deben hacerse sobre una base periódica y sistemática.

MEDICIÓN DE LAS CARACTERÍSTICAS DEL MANTENIMIENTO


Se han discutido varias de las propiedades del software que lo hacen (o no) fácil de entender, reforzar y corregir.
Usando estos factores para medir el software cuando se entrega, se puede predecir la probabilidad de que el
software sea posible de mantener. Durante el proceso de mantenimiento, las medidas pueden guiar las
actividades, contribuyendo a evaluar el impacto de un cambio o valorizando los méritos relativos de algunas
propuestas de cambios o enfoques.

La facilidad de mantenimiento no se restringe al código; describe muchos productos del software, incluyendo la
especificación, el diseño y los documentos del plan de prueba. Por lo tanto, se necesitan medidas de la facilidad
de mantenimiento para todos los productos que se espera mantener.

La facilidad de mantenimiento puede pensarse de dos maneras, que reflejan las vistas externas e internas del
software. La facilidad de mantenimiento como se ha definido en este libro, es un atributo externo del software,
dado que no solo depende del producto, sino también de la persona que realiza el mantenimiento, de la
documentación y de las herramientas de soporte y del uso propuesto del software. Esto es, no es posible medir la
facilidad de mantenimiento sin supervisar el comportamiento del software en un ambiente dado.
Por otra parte, sería conveniente medir la facilidad de mantenimiento antes de concretar la entrega del software,
a fin de tener una cierta noción de los recursos requeridos para apoyar la resolución de cualquier problema que
pueda ocurrir. Para este tipo de medida, se utilizan los atributos internos del software (es decir, aquellos que se
relacionan con la estructura) y se establece que estos predicen las medidas externas. Dado que este enfoque no
implica una medida directa, se debe ponderar la viabilidad de un enfoque indirecto con la exactitud del enfoque
externo.

Visión externa de la facilidad de mantenimiento:


Para medir la facilidad de mantenimiento definiéndola como el tiempo medio para realizar la reparación de un
software, se necesitan cuidadosos registros de la siguiente información, para cada uno de los problemas:
 El momento en que se da parte del problema.
 Toda pérdida de tiempo debida a retrasos administrativos.
 El tiempo que demanda el análisis del problema.
 El tiempo que se requiere para especificar los cambios que se deben realizar.
 El tiempo empleado para hacer el cambio.
 El tiempo necesario para probar el cambio.
 El tiempo requerido para documentar el cambio.

La Figura 11.5 muestra el tiempo medio de reparación de los diversos subsistemas que integran el software de
una gran empresa británica. Esta información resultaba muy útil para identificar los subsistemas causantes de la
mayoría de los problemas y planificar las actividades de mantenimiento preventivo (Pfleeger, Fenton y Page
1994). Utilizando gráficos como éste para el tiempo medio de reparación, se puede determinar si un sistema está
tornándose más o menos mantenible.

Existen otras medidas (dependientes del entorno o ambiente) que también pueden ser útiles, si se encuentran
disponibles:
 Relación entre tiempo total de implementación del cambio y cantidad total de cambios realizados.
 El número de problemas no resueltos.
 El tiempo gastado en los problemas no resueltos.
 El porcentaje de cambios que introducen nuevos defectos.
 El número de componentes modificados para implementar un cambio.
En conjunto, estas medidas reflejan el grado de actividad de mantenimiento y la efectividad del proceso de
mantenimiento.

Atributos internos que afectan la facilidad de mantenimiento:


Numerosos investigadores han propuesto medidas para los atributos internos relacionados con la facilidad de
mantenimiento. Por ejemplo, las medidas de complejidad descritas en los capítulos precedentes a menudo se
correlacionan con el esfuerzo de mantenimiento; es decir, cuanto más complejo es el código, es mayor el
esfuerzo requerido para mantenerlo. Es importante recordar que correlación no es lo mismo que medida. Pero
existe una conexión clara e intuitiva entre productos mal estructurados y pobremente documentados con su
respectiva facilidad de mantenimiento.

Número ciclomático. Una de las medidas frecuentemente utilizadas durante el mantenimiento es el número
ciclomático, definido inicialmente por McCabe (1976). EL número ciclomático es una métrica que captura un
aspecto de la complejidad estructural del código fuente midiendo el número de caminos linealmente
independientes a través del código. Basado en conceptos de la teoría de grafos, se calcula convirtiendo el código
en su gráfico de flujo de control equivalente, y utilizando las propiedades del grafo para, determinar la métrica.

Grafo con n nodos y e aristas.

En este caso n es 6 y e es 8.

Un resultado de la teoría de
grafos indica, para este caso,
que el número de caminos
linealmente independientes a
través del grafo es 4, valor
que resulta de:
e–n+2
GRAFO DE CONTROL DE FLUJO GRAFO EQUIVALENTE
Figura 11.6. Ejemplo para el cálculo del número ciclomático.

McCabe demostró que el número ciclomático también coincide con el número de declaraciones de decisión en el
código más uno. Una manera fácil de calcular el número ciclomático a partir del gráfico es observar la forma en
que el gráfico divide al plano en segmentos.

Un cálculo similar puede hacerse a partir del diseño de un componente, de modo que el número ciclomático se
utiliza a menudo para evaluar algunas alternativas de diseño, incluso antes de dar comienzo a la codificación. El
número ciclomático también es útil en muchos otros contextos. Indica cuántos caminos independientes necesitan
ser probados para proporcionar la cobertura de prueba, por lo que a menudo se calcula y se utiliza para
determinar la estrategia de la prueba.

En el mantenimiento, el número de caminos independientes o, lo que es equivalente, uno más del número de
decisiones, indica cuánto se debe comprender y rastrear cuando se examina o se cambia un componente. Por lo
tanto, muchos investigadores y profesionales encuentran útil observar el efecto de un cambio o arreglo sobre el
número ciclomático de un componente o sistema; si el cambio o arreglo resulta en un aumento drástico en el
número ciclomático, entonces los encargados del mantenimiento pueden tomar la decisión de volver a pensar el
diseño del cambio o el arreglo. De hecho, la segunda ley de Lehman de la evolución del software predice que el
número ciclomático (y otras medidas de la complejidad) aumentará a medida que el sistema evoluciona.

Es necesario obrar con cautela al usar esta o cualquier otra medida para representar toda la complejidad del
software. Es verdad que un aumento en el número de decisiones o caminos normalmente hace que el código sea
más difícil de entender. Pero existen otros atributos que contribuyen a la complejidad, que no se capturan a
través de la estructura del código. Por ejemplo, la jerarquía de herencia de los programas orientados a objetos
puede ser bastante compleja, al tener ramificaciones que no son evidentes al estudiar un componente aislado,
fuera del contexto. Los investigadores continúan buscando los mejores métodos para definir y medir la
complejidad, y ayudar a los desarrolladores en su objetivo de construir sistemas simples y fáciles de mantener.

Otras medidas del producto. Hay muchos atributos del producto que ayudan a entender la facilidad de
mantenimiento y a predecir las probables fuentes de problemas. Algunas organizaciones usan reglas basadas en
medidas del componente, como el tamaño. [[Por ejemplo, Móller y Paulish (1993) muestran que en Siemens, los
componentes más pequeños (en términos del número de líneas de código) tenían una densidad de defectos más
alta que los más grandes.]] Otros investigadores han usado la información sobre la profundidad de anidamiento,
el número de operadores y operandos y los abanicos de entrada y de salida (fan-in/fan-out) para predecir la
calidad del mantenimiento. En el Cuadro Destacado 11.5 se describe un enfoque usado por Hewlett-Packard para
crear un índice de facilidad de mantenimiento.

CUADRO DESTACADO 11.5 - MEDIDAS DE MANTENIMIENTO EN HEWLETT-PACKARD


Oman y Hagemeister (1992) han sugerido que la facilidad de mantenimiento puede ser modelada utilizando tres
dimensiones: la estructura de control, la estructura de la información y la tipografía, a saber, denominación y comentarios del
sistema en mantenimiento. Definen métricas para cada dimensión y las combinan en un índice de facilidad de mantenimiento
para el sistema completo.
Este índice fue usado por Coleman el al.il 994) en Hewlett-Packard (HP) para evaluar la facilidad de mantenimiento de
varios sistemas de software. En primer lugar, el índice fue calibrado con un gran número de métricas y se calcula un índice
polinómico ajustado utilizando el número ciclomático extendido, líneas de código, cantidad de comentarios y una medida del
esfuerzo definida por Halstead (1997). Después se aplicó el polinomio a 714 componentes que contenían 236.000 líneas de
código C desarrollado por un tercero. El análisis de la facilidad para el mantenimiento produjo un ordenamiento de los
componentes que ayudó a HP a identificar los que eran más difíciles de mantener. Los resultados corroboraron la corazonada
del personal de mantenimiento acerca del grado de dificultad que conlleva mantener sistemas.
Los polinomios también se usaron para comparar dos sistemas de software que fueran similares en tamaño, número de
módulos, plataformas y lenguajes. Una vez más los resultados corroboraron los pensamientos de los ingenieros de UP. En
varios análisis subsiguientes, el polinomio ha continuado concordando con la intuición de los mantenedores. Pero las medidas
han proporcionado información adicional que da respaldo a decisiones del tipo hacer-comprar hecho, calificando
componentes para el mantenimiento preventivo y perfectivo y la evaluación de los efectos de la reingeniería.
Porter y Selby (1990) usaron una técnica estadística llamada análisis de árbol de clasificación, para identificar
aquellas medidas del producto que actúan como mejores predictores de los errores de la interfaz que
probablemente aparezcan durante el mantenimiento. El árbol de decisión que resulta del análisis de la
clasificación de sus datos hace pensar en restricciones mensurables basadas en la historia pasada:
 Entre 4 y 8 revisiones durante el diseño y por lo menos 15 enlaces de datos sugieren que es probable la
existencia de defectos en la interfaz.
 Los problemas de la interfaz son probables en un componente cuya función primaria es administrar
archivos donde ha habido por lo menos 9 revisiones durante el diseño.

Estas sugerencias son particulares para cada juego de datos y no están pensadas como pautas generales para
cualquier organización. Sin embargo, la técnica puede aplicarse a cualquier base de datos que contenga la
información sobre esta clase de medidas.

Para los productos textuales, la legibilidad afecta la facilidad de mantenimiento. La medida de legibilidad más
conocida es el índice de niebla, F, propuesto por Gunning. La medida corresponde aproximadamente al número
de años de aprendizaje que necesita una persona para poder leer un pasaje con facilidad, comprendiendo
correctamente el significado. Para los documentos grandes, esta medida normalmente se calcula a partir de una
muestra del texto.

TÉCNICAS Y HERRAMIENTAS PARA EL MANTENIMIENTO:


Una manera de reducir el esfuerzo de mantenimiento es edificar la calidad desde el comienzo. Tratar de imponer
buen diseño y estructura dentro de un sistema ya construido no resulta tan exitoso como lo es construir el
sistema correctamente desde el comienzo. Sin embargo, además de las buenas prácticas, hay varias otras
técnicas que refuerzan la comprensión y la calidad.

La gestión de configuración:
El seguimiento de los cambios y sus efectos en otros componentes del sistema no es una tarea fácil. Mientras
más complejo es un sistema, son más los componentes que resultan afectados por un cambio. Por esta razón, la
gestión de configuración, importante durante el desarrollo, es crítica durante el mantenimiento.

Comité de control de configuración. Debido a que muchos de los cambios de mantenimiento son instigados por
clientes y usuarios (cuando se producen fallas o cuando se piden mejoras), se establece un comité de control de
configuración para supervisar el proceso de cambio. Este comité está formado por representantes de todas las
partes interesadas, incluso clientes, desarrolladores y usuarios. Cada problema se atiende de la manera siguiente:

1) Al descubrir un problema el usuario, el cliente o el desarrollador, registra los síntomas en un formulario de


control de cambio formal. Alternativamente, quien descubre el problema solicita un perfeccionamiento:
una nueva función, una variante de una función ya existente o la eliminación de una función. El
formulario, debe incluir información sobre la forma en que trabaja el sistema, la naturaleza del problema
o de la mejora y cómo se supone que trabaja el sistema.
2) El cambio propuesto se informa al comité de control de configuración.
3) El comité de control de configuración se reúne para discutir el problema. Primero determina si la
propuesta se debe a que no se cumplió un requerimiento o se trata de una solicitud de mejora. Esta
decisión normalmente indica quién pagará por los recursos necesarios para llevar a cabo el cambio.
4) Cuando se trata de una falla, el comité discute el origen probable del problema. Si es un pedido de
perfeccionamiento, debate sobre las partes del sistema que probablemente sean afectadas por el cambio.
En ambos casos, programadores y analistas pueden describir el alcance de cualquiera de los cambios que
se necesitan y el lapso de tiempo que les llevará la implementación. El comité asigna prioridad o nivel de
severidad a la solicitud, y le asigna a un programador o analista la responsabilidad de hacer los cambios
apropiados al sistema.
5) El analista o programador designado localiza el origen del problema o los componentes involucrados con
la solicitud, e identifica los cambios necesarios. El programador o analista, que trabaja con una copia de
prueba en lugar de la versión operacional del sistema, implementa los cambios y los prueba para asegurar
que funcionan correctamente.
6) El responsable del cambio trabaja con el bibliotecario de programas para controlar la instalación de los
cambios en el sistema operacional. Se actualiza toda la documentación relevante.
7) El programador o analista archiva un informe de cambio que describe en detalle todos los cambios
realizados.

El control del cambio. El paso más crítico en el proceso descrito es el número 6. En cualquier momento, el equipo
de gestión de configuración debe conocer el estado de cualquier componente o documento en el sistema. Por
consiguiente, la gestión de configuración debe dar énfasis a la comunicación entre aquellas personas cuyas
acciones afectan al sistema. Cashman y Holt (1980) sugieren que siempre se saben las respuestas a las siguientes
preguntas:
 Sincronización: ¿Cuándo se hizo el cambio?
 Identificación: ¿Quién lo hizo?
 Denominación: ¿Qué componentes del sistema se cambiaron?
 Autenticación: ¿Fue hecho correctamente?
 Autorización: ¿Quién autorizó la realización del cambio?
 Ruta seguida: ¿Quién fue notificado del cambio?
 Cancelación: ¿Quién puede cancelar la solicitud de cambio?
 Delegación: ¿Quién es el responsable por el cambio?
 Valoración: ¿Cuál es la prioridad del cambio?

Cabe destacar que estas preguntas son cuestiones de gestión, no tienen carácter técnico. Es necesario aplicar los
procedimientos para manejar cuidadosamente el cambio.

Se puede contribuir a la gestión de cambio siguiendo varias convenciones. Primero, se asigna un código o número
de identificación a cada versión activa del sistema. Cuando una versión se modifica, se le asigna un código o
número de revisión a cada componente que resulte cambiado. Se guarda un registro de cada versión y estado del
componente, así como una historia de todos los cambios. Entonces, en cualquier punto de la vida del sistema, el
equipo de gestión de configuración puede identificar la versión operacional actual del sistema y el número de
revisión de cada componente en uso. El equipo también puede averiguar cómo difieren las diversas revisiones,
quién hizo los cambios y por qué fueron realizados.
Desde la perspectiva de un estudiante, tal vez estas convenciones de gestión de configuración probablemente
parezcan innecesarias. Los proyectos de asignatura normalmente se manejan en forma personalizada o con la
participación de un grupo reducido de programadores, usando la comunicación verbal para rastrear las
modificaciones y perfeccionamientos. Sin embargo, no cuesta imaginar el caos que resultaría si se aplicaran las
mismas técnicas en el desarrollo y mantenimiento de un sistema de 200 componentes. A menudo, los sistemas
grandes son desarrollados por grupos independientes que tienen que trabajar simultáneamente en diferentes
aspectos del sistema; a veces estos grupos se encuentran en diferentes lugares de una ciudad o incluso en
ciudades diferentes. Cuando la falta de una buena comunicación lleva a una falla del sistema, el equipo de gestión
de configuración debe ser capaz de restaurar el sistema a su condición estable anterior; este paso sólo puede
llevarse a cabo cuando el equipo sabe con exactitud qué cambios se han hecho, a qué componentes, quién los
hizo y cuando se hicieron.

Análisis de impacto:
En los modelos tradicionales del ciclo de vida del software, el mantenimiento se representa como una
etapa que comienza después de que el software se despliega en toda su extensión. Sin embargo, el
mantenimiento del software es dependiente de los requerimientos del usuario y empieza con ellos. Por lo tanto,
los mismos principios de desarrollo del buen software se aplican al desarrollo y a los procesos de mantenimiento.
Dado que el correcto desarrollo del software soporta los cambios, el cambio constituye una consideración
necesaria a lo largo de la vida de un producto de software. Es más, un cambio aparentemente menor a menudo
es más extenso (y por consiguiente más costoso) que lo esperado. El análisis de impacto es la evaluación de los
numerosos riesgos asociados con el cambio, incluyendo las estimaciones de los efectos sobre los recursos, el
esfuerzo y el cronograma.
Preventivo
Adaptativo
Correctivo
Perfectivo

Figura 11.7. Actividades del mantenimiento de software.


Los efectos de múltiples cambios en un sistema pueden verse reflejados en la documentación inadecuada o
desactualizada resultante, en el software reparado en forma incompleta o incorrecta, en la escasa estructuración
del diseño o del código, en los artefactos que no conforman las normas, etc. El problema es compuesto, por la
complejidad creciente, por el mayor tiempo que necesitan los desarrolladores para entender el código que debe
cambiarse, y por el incremento de los efectos laterales que el cambio puede tener en otras partes del sistema.
Estos problemas aumentan el costo de mantenimiento y a la gestión le conviene mantener este costo bajo
control. Se puede utilizar el análisis de impacto para ayudar a controlar los costos de mantenimiento.

Pfleeger y Bohner (1990) han investigado acerca de las formas de medir el impacto de un cambio propuesto para
determinar los riesgos y ponderar las diversas opciones. Por consiguiente, describen un modelo de
mantenimiento del software que incluye realimentación medida. El diagrama de la Figura 11.7 muestra las
actividades que se realizan cuando se solicita un cambio. Las flechas etiquetadas que aparecen en la parte inferior
representan medidas que proporcionan información que los gerentes pueden utilizar para decidir cuándo y cómo
realizar un cambio.

Un subproducto (workproduct) es cualquier artefacto de desarrollo cuyo cambio es importante. En este sentido,
los requerimientos, los componentes del diseño y del código, los casos de prueba y la documentación son
subproductos; la calidad de uno puede afectar la calidad de los otros, de modo que cambiarlos puede tener
consecuencias importantes. Se puede evaluar el impacto del cambio para todos los subproductos. Para cada uno,
la facilidad de rastreo vertical expresa las relaciones entre las partes del subproducto. Por ejemplo, el rastreo
vertical de los requerimientos describe las interdependencias entre los requerimientos del sistema. La facilidad
de rastreo horizontal se ocupa de las relaciones de los componentes entre conjuntos de subproductos. Por
ejemplo, cada componente de diseño se rastrea hasta los componentes del código que implementan esa parte
del diseño. Ambos tipos de rastreo son necesarios para entender el juego completo de relaciones que se evalúan
durante el análisis de impacto.

Tanto el rastreo horizontal como el vertical pueden representase usando grafos dirigidos. Un grafo dirigido es
simplemente una colección de objetos, llamados nodos, y una colección asociada de pares ordenados de nodos,
denominados ariscas. El primer nodo de la arista se designa como nodo fuente y el segundo es el nodo destino.
Los nodos representan información contenida en los documentos, artículos y otros artefactos. Cada artefacto
contiene un nodo para cada componente. Por ejemplo, es posible representar el diseño como una colección de
nodos, con un nodo para cada componente del diseño, y de igual manera la especificación de requerimientos
tiene un nodo para cada requerimiento. Las aristas dirigidas representan las relaciones internas en un
subproducto y entre los diversos subproductos.

La Figura 11.8 muestra cómo quedan determinadas las relaciones gráficas y los enlaces de rastreo entre
subproductos relacionados. Se examina cada requerimiento y se dibuja un eslabón entre el requerimiento y los
componentes del diseño que lo implementan. A su vez, se une cada componente del diseño con los componentes
del código que implementan. Finalmente, se conecta cada módulo del código con el juego de casos de prueba
que le corresponden. Las uniones resultantes forman el gráfico subyacente que exhibe las relaciones entre los
subproductos.
La Figura 11.9 muestra el aspecto típico de un gráfico de rastreo global. Cada artefacto mayor del proceso
(requerimientos, diseño, código y prueba) se muestra como una caja alrededor de sus nodos constitutivos. Las
aristas sólidas dentro de cada caja son las relaciones de rastreo verticales para los componentes en la caja. Las
aristas punteadas entre las cajas representan los enlaces de rastreo horizontal para el sistema. En el Cuadro
Destacado 11.6 se describe cómo fue aplicado este enfoque en Ericsson.
Pruebas

Figura 11.8.Rastreo horizontal en subproductos de software.

Requerimientos Diseño Código Prueba


Figura 11.9. Gráfico subyacente para el mantenimiento.
Existes bastantes indicios que indican que algunas medidas de complejidad son buenos indicadores de probable
tasa de defectos y esfuerzo (Carda y Glass 1990). Estos conceptos pueden ampliarse a las características del
gráfico de rastreo a fin de evaluar el impacto de un cambio propuesto. [[Por ejemplo, consideremos el gráfico de
rastreo vertical dentro de cada caja de la Figura 11.9. El número total de nodos, el número de aristas para las que
un nodo es destino (el llamado grado de entrada al nodo) y la cantidad de aristas para las que el nodo es la fuente
(llamado grado de salida), además de las medidas como el número ciclomático, pueden ser evaluados antes y
después del cambio.]] Si el tamaño y la complejidad del grafo parecen aumentar con el cambio, es probable que
también aumenten el tamaño y la complejidad de los subproductos correspondientes. Con esta información, el
comité de configuración puede decidir llevar a cabo el cambio de una manera diferente o no hacerlo. Aun cuando
se decida hacer el cambio conforme a lo propuesto, los riesgos involucrados se entenderán más cabalmente con
este cuadro basado en medidas.

Las medidas del rastreo vertical son medidas del producto que reflejan el efecto del cambio en cada uno de los
subproductos que se deben mantener. Las medidas de las características del gráfico de rastreo horizontal
representan una visión del proceso de cambio. Para cada par de subproductos, se puede formar un subgrafo de
las relaciones entre los dos: uno que relacione requerimientos y diseño, y otro que vincule el diseño con el
código, y un tercero que relacione el código y los casos de prueba. Luego se miden el tamaño y la complejidad de
las relaciones para determinar el impacto adverso. Es más, observando el gráfico de rastreo horizontal global se
puede inferir si los rastreos serán más difíciles o más simples después del cambio. Pfleeger y Bohner (1990)
consideran el mínimo conjunto de caminos que abarca el gráfico; entonces, si el número de caminos
abarcados aumenta después del cambio, es probable que el sistema sea más pesado y difícil mantener. De
manera similar, si los grados de entrada y de salida de los nodos aumentan sustancialmente, el sistema puede ser
más difícil de mantener en el futuro.

Herramientas automatizadas de mantenimiento:


El rastreo del estado de todos los componentes y pruebas es un trabajo formidable. Afortunadamente, hay
muchas herramientas automatizadas que contribuyen a mantener el software. Aquí se describen algunos tipos de
herramientas:

Editores de texto. Los editores de texto son útiles para el mantenimiento de varias maneras. Primero, un editor
puede copiar código o documentación de un lugar a otro, evitando los errores que se pueden producir al duplicar
texto. Segundo, algunos editores de texto rastrean los cambios relativos a un archivo básico, guardado en un
archivo separado. Muchos de estos editores cronometran y estampan la fecha de cada entrada al texto y
proporcionan una manera de pasar de una versión actual de un archivo a una anterior, si es necesario.

Comparadores de archivo. Una herramienta útil durante el mantenimiento es un comparador de archivos, que
compara dos archivos e informa sobre sus diferencias. Se los utiliza a menudo para asegurar que dos sistemas o
programas que supuestamente son idénticos realmente lo son. El programa lee archivos y puntualiza las
diferencias.

Compiladores y vinculadores (linkers). Los compiladores y los vinculadores (linkers) suelen tener características
que simplifican el mantenimiento y la gestión de configuración. Un compilador verifica la existencia de defectos
de sintaxis en el código, y en muchos casos señala la ubicación y el tipo de defecto. Los compiladores para
algunos lenguajes, como Modula-2 y Ada, también verifican la consistencia a través de componentes compilados
por separado.
Cuando el código se ha compilado correctamente, el vinculador (linker) (también conocido como editor de
vínculos) eslabona el código con los otros componentes necesarios para ejecutar el programa. [[Por ejemplo, un
vinculador (linker) conecta un archivo filename.h con su archivo de filename.c correspondiente en lenguaje C.]]
Un vinculador (linker) también puede notar las llamadas subrutina, biblioteca y macroinstrucciones, trayendo
automáticamente los archivos necesarios para hacer un todo compilable. Algunos vinculadores también rastrean
los números de la versión de cada uno de los componentes requeridos, de modo que solamente puedan
eslabonarse versiones apropiadas y compatibles. Estos auxilios técnicos eliminan los problemas que causa el uso
de una copia incorrecta de un sistema o subsistema cuando se prueba un cambio.

Herramientas de depuración. Las herramientas de depuración y puesta a punto ayudan a realizar el


mantenimiento ya que permiten rastrear paso a paso la lógica de un programa, examinar los contenidos de los
registros y áreas de memoria y poner señales y punteros.
Generadores de referencias cruzadas. Los sistemas automatizados generan y almacenan las referencias cruzadas
para brindar, tanto al equipo de desarrollo como al de mantenimiento, el control más firme sobre las
modificaciones del sistema. Por ejemplo, algunas herramientas de cruce de referencias actúan como un almacén
de requerimientos del sistema, y también mantienen los eslabones hacia otros documentos del sistema y al
código que relacionan con cada requerimiento. Cuando se propone un cambio a un requerimiento, se puede usar
la herramienta para determinar qué otros requerimientos y componentes del diseño o del código resultarán
afectados.
Algunas herramientas para el cruce de referencias contienen un juego de fórmulas lógicas llamadas condiciones
de comprobación; entonces, si todas las fórmulas arrojan un valor “verdadero”, el código satisface las
especificaciones que lo generaron. Este rasgo es especialmente útil durante el mantenimiento, para asegurar que
el código cambiado todavía cumplimenta sus especificaciones.

Analizadores de código extáticos. Los analizadores de código estáticos calculan información sobre los atributos
estructurales del código, como la profundidad de anidamiento, el número de caminos abarcados, los números
ciclomáticos, el número de líneas de código y las sentencias fuera de alcance. Cada vez que se construyen nuevas
versiones de un sistema que está en mantenimiento, se puede calcular esta información para ver si sus
componentes se están volviendo más grandes, más complejos y más difíciles mantener. Las medidas también
ayudan a decidir entre algunas alternativas de diseño, especialmente cuando se están rediseñando porciones de
código existente.

Repositorios de gestión de configuración. La gestión de configuración sería imposible sin las bibliotecas de
información que controlen el proceso de cambio. Estos almacenamientos pueden guardar informes del problema,
incluso la información sobre cada problema, la organización que lo informa y la organización que lo arregla.
Algunos almacenamientos les permiten a los usuarios guardar las etiquetas sobre el estado de problemas
informados en los sistemas que ellos están utilizando.

REJUVENECIMIENTO DEL SOFTWARE:


En muchas organizaciones que poseen gran cantidad de software, el mantenimiento de los sistemas constituye
un desafío. [[Para ver por qué consideramos una compañía de seguros que ofrece un nuevo producto del rubro
seguros de vida. Para dar soporte a ese producto, la compañía desarrolla el software para el tratamiento de las
pólizas de seguro, información sobre el poseedor de pólizas, información legal e información contable. Tales
pólizas pueden necesitar soporte durante docenas de años; en algunos casos el software no puede retirarse hasta
que fallece el último poseedor de pólizas y se paga la cobertura al beneficiario. Como resultado, es probable que
la compañía de seguros mantenga muchas aplicaciones diferentes en una variedad de plataformas con
numerosos lenguajes de aplicación.]] Las organizaciones que se encuentran en esta situación deben tomar
decisiones difíciles sobre cómo hacer más mantenibles sus sistemas. Las opciones pueden ir desde el
perfeccionamiento hasta el completo reemplazo por una nueva tecnología; cada opción está pensada para
conservar o incrementar la calidad del software, mientras se mantienen los costos lo más bajos posible.

El rejuvenecimiento del software encara este desafío de mantenimiento, intentando aumentar la calidad global
de un sistema existente. Contempla retrospectivamente los subproductos de un sistema para intentar derivar la
información adicional o para reformarlos en un modo más comprensible. Hay varios aspectos del
rejuvenecimiento del software a considerar, entre los que se incluyen:
 Redocumentación (reestructuración de documentos).
 Reestructuración.
 Ingeniería inversa.
 Reingeniería (ingeniería progresiva).

Cuando se redocumenta un sistema se realiza un análisis estático del código fuente, generando información
adicional para ayudar al personal de mantenimiento a entender y referenciar el código. El análisis no hace nada
para transformar el código real; deriva meramente la información. Sin embargo cuando se reestructura el
software, realmente se cambia el código, transformando un producto sin estructura en código bien estructurado.
Ambas técnicas se centran solamente en el código fuente. Para realizar la ingeniería inversa de un sistema se
mira todavía más atrás del código fuente, a los productos que lo precedieron, recreando el diseño y la
información de especificación del código. La reingeniería es aún más amplia, en este caso se hace la ingeniería
inversa de un sistema existente, y después se realiza la ingeniería de avance, donde se implementan los cambios
a la especificación y al diseño que completan el modelo lógico, es decir, se genera un nuevo sistema a partir de la
especificación y el diseño revisados. La Figura 11.10 muestra las relaciones entre los cuatro tipos de
rejuvenecimiento.

Por supuesto, es imposible esperar la recreación de todos los productos intermedios a partir de una pieza de
código fuente dada. No obstante, pueden reforzarse algunas de las características esenciales de alguno de los
subproductos o se pueden embellecer de algún modo. El grado al cual puede extraerse información del producto
final depende de varios factores (Bohner 1990):
 Lenguaje(s) utilizado(s).
 Interfaz con la base de datos.
 Interfaz de usuario.
 Interfaces a los servicios del sistema.
 Interfaces a otros lenguajes.
 Madurez y estabilidad
del dominio.
 Herramientas
disponibles.

La habilidad, conocimiento y
experiencia del personal de
mantenimiento también juegan
un papel importante en el
grado en que la información
puede ser interpretada y
utilizada con éxito.
Redocumentación:
La redocumentación implica un análisis del código fuente para producir la documentación del sistema. Se pueden
examinar el uso de las variables, llamadas a componentes, caminos del control, el tamaño del componente,
parámetros de llamadas, caminos de prueba y otras medidas relacionadas que permitan entender lo que el
código hace y cómo lo hace. La información producida por un análisis estático del código puede ser gráfica o
textual.

La Figura 11.11 ilustra el proceso de reestructuración de documentos. Es típico que el personal de mantenimiento
comience este proceso sometiendo el código a una herramienta del análisis. Los resultados de este proceso
pueden generar:
 Relaciones del componente.
 Jerarquías de clases.
 Tablas de interfaz de datos.
 La información de los diccionarios de datos.
 Diagramas o tablas de flujo de datos.
 Diagramas o tablas de flujo de control.
 Pseudocódigo.
 Caminos de prueba.
 Referencias cruzadas de componentes y variables.

La información obtenida, en forma gráfica, textual o tabular, puede usarse para evaluar si un sistema requiere o
no una reestructuración. Sin embargo, dado que no hay ningún mapeo entre la especificación y el código
reestructurado, la documentación resultante refleja lo que es, en lugar de lo que debe ser.
Reestructuración:
El software se reestructura para hacerlo más fácil de entender y cambiar. Las herramientas ayudan a concretar
esta tarea interpretando el código fuente y representándolo internamente. Después se utilizan reglas de
transformación para simplificar la representación interna y los resultados se reformulan como código
estructurado. Aunque algunas herramientas sólo producen código fuente, otras tienen funciones de soporte para
generar estructura, volumen, complejidad y otra información. Estas medidas se usan para determinar la facilidad
de mantenimiento del código y evaluar los efectos de la reestructuración. Por ejemplo, se pretende que las
medidas de complejidad indiquen una disminución en la complejidad después de efectivizar la reestructuración.

La Figura 11.12 presenta las tres actividades principales que implica la reestructuración. En primer término, el
análisis estático proporciona la información que se va a utilizar para representar el código como una red
semántica o un grafo orientado. Esta representación no necesariamente es leída con facilidad por las personas
normalmente solo es utilizada por una herramienta automatizada.

Luego, la representación se refina mediante simplificaciones sucesivas, basadas en las técnicas de


transformación. Por último, la representación refinada se interpreta y se utiliza para generar un cuerpo
equivalente de código estructurado para el sistema (normalmente para el mismo compilador).

Ingeniería inversa:
La ingeniería inversa, como la reestructuración de documentos, proporciona información de especificación y
diseño acerca del sistema de software a partir de su código fuente. Sin embargo, la ingeniería inversa va más allá,
porque intenta recuperar información de ingeniería del producto basándose en la especificación del software y
los métodos de diseño; esta información se guarda entonces en una forma que permite manipularla. La
información extraída no es necesariamente completa, porque muchos de los componentes fuente suelen estar
asociados con uno o más componentes de diseño. Por esta razón, un sistema descrito mediante un proceso de
ingeniería inversa puede tener realmente menos información que el sistema original.
Gracias a las estaciones de trabajo gráficas y a las herramientas de gestión de almacenamiento, puede
automatizarse gran parte de la ingeniería inversa. Se pueden presentar y manipular diseños gráficos y controlar
un almacén de datos recopilado por las herramientas que se utilizan.

La Figura 11.13 muestra el proceso de ingeniería inversa. En primer lugar se somete el código a una herramienta
de ingeniería inversa que interpreta la estructura y da nombre a la información, y construye las salidas de manera
muy semejante al proceso de reestructuración de documentos. Los métodos aceptados de análisis y diseño
estructurado sirven como mecanismos aptos de comunicación para articular la información de la ingeniería
inversa, tales como diccionarios de datos, flujo de datos, flujo de control y diagramas entidad-relación-atributo.

La llave para revertir la ingeniería es su aptitud para abstraer las especificaciones a partir del código fuente
detallado de la aplicación. Persisten, sin embargo, algunos obstáculos significativos antes de que la ingeniería
inversa pueda usarse universalmente. Los sistemas de tiempo real presentan un problema: la correspondencia
entre la aplicación y el plan es dispersa, debido a las frecuentes optimizaciones del desempeño. Un segundo
problema ocurre cuando se implementan sistemas sumamente complejos, con convenciones de denominación
muy concisas o incomprensibles. Cuando se aplican las herramientas de la ingeniería inversa a este tipo de
sistemas, la información modelada es de valor limitado.

La ingeniería inversa es exitosa cuando las expectativas son bajas. Es decir, las herramientas trabajan bien,
determinando todos los elementos de datos relacionados y las llamadas a un componente particular. Pueden
desplegar la estructura de un sistema complejo y reconocer inconsistencias o violaciones de los estándares de
diseño.

Reingeniería:
La reingeniería es una extensión de la ingeniería inversa. Considerando que la ingeniería inversa abstrae la
información, la reingeniería produce el nuevo código fuente del software sin cambiar la función del sistema
global. La Figura 11.14 presenta los pasos de este proceso. Primero, el sistema se somete al proceso de ingeniería
inversa y se lo representa internamente, con lo cual queda preparado para las modificaciones, por personas y
computadora, basadas en los métodos actuales de especificación y diseño de software. Después, se corrige o se
completa el modelo del sistema de software. Finalmente, se genera el nuevo sistema conforme a esta nueva
especificación o diseño.

Las entradas al proceso de reingeniería están constituidas por los archivos de código fuente, los correspondientes
a la base de datos, los de generación de pantallas y otros archivos similares relacionados con el sistema. Cuando
el proceso está completo, genera toda la documentación del sistema, incluso la especificación y el diseño y el
nuevo código fuente.

Dado que una reingeniería totalmente automatizada es improbable en un futuro cercano, el proceso debe
involucrar una combinación de transformación e interacción humana. Las representaciones incompletas se
pueden completar a mano, y un diseñador experimentado puede reforzar los diseños antes de generar el nuevo
sistema.

El futuro del rejuvenecimiento:


Dado que el mantenimiento del software no siempre atrae a los profesionales como lo hace el desarrollo de
nuevo software, una problemática como el rejuvenecimiento no consigue tanta atención como otras relacionadas
con nuevos desarrollos. Sin embargo, algunos avances le han proporcionado una mayor visibilidad al
rejuvenecimiento. Las herramientas comerciales de ingeniería inversa recuperan sólo parcialmente el diseño de
un sistema de software; pueden identificar, presentar y analizar la información del código fuente, pero no
reconstruyen, ni capturan ni expresan abstracciones del diseño que no están explícitamente representados en el
código fuente.
La información de código fuente no contiene mucha información sobre el diseño original, por lo que el resto debe
reconstruirse a partir de inferencias. Por lo tanto los intentos de ingeniería inversa más exitosos se han producido
en dominios estables y muy bien entendidos como son los sistemas de información. Aquí, el sistema típico es
estándar, el lenguaje (por lo general COBOL) es relativamente simple y bien estructurado, y hay muchos expertos
del dominio.

En otros dominios, la recuperación del diseño sólo es posible si se cuenta con la información del código, la
documentación del diseño existente, bastante experiencia del personal y un conocimiento general sobre el
dominio del problema. Se necesita un conocimiento lingüístico informal sobre el dominio del problema y los
modismos de la aplicación antes de que un diseño completo pueda encenderse y reconstruirse. Es así que el
rejuvenecimiento del software avanzará cuando la tecnología y los métodos pueden capturar las reglas, las
políticas, las decisiones de diseño, la terminología, las convenciones sobre denominaciones y otra información
informal.

Al mismo tiempo, la formalización de las notaciones de diseño y la introducción de modelos de dominio


ampliarán la información disponible para entender y mantener un sistema de software. También pueden
esperarse mejoras en la tecnología de la transformación, para dar soporte a más dominios de aplicación y
representaciones más completas que permitirán que la reingeniería se automatice más.

También podría gustarte