This description provides background information for technologies for
optimizing maintenance environments. We recommend Cyclomatic Complexity; Halstead Complexity Measures; Maintainability Index Technique for
Measuring Program Maintainability; and Function Point Analysis as concurrent reading, as they contain information about specific technologies.
Technologies specific to the maintenance of software evolved (and are still
evolving) out of development-oriented technologies. As large systems have
proliferated and aged, the special needs of the operational environment have
begun to emerge. Maintenance is defined here as the modification of a software
product after delivery to correct faults, improve performance or other
attributes, or to adapt the product to a changed environment
[IEEE
83]. Historically, the software lifecycle has usually focused on
development. However, so much of a system's cost is incurred during its
operational lifetime that maintenance issues have become more important and,
arguably, this should be reflected in development practices. Systems are
required to last longer than originally planned; inevitably, the percentage of
costs going to maintenance has been steadily climbing. Hewlett-Packard
estimates that 60% to 80% of its R&D personnel are involved in maintaining
existing software, and that 40% to 60% of production costs were directly
related to maintenance
[Coleman 94]. There was a rule of thumb that eighty percent of a Department of Defense (DoD) system's cost is in maintenance; older Cheyenne Mountain Complex systems may have surpassed ninety percent. Yet software development practices still do not put much emphasis on making the product highly maintainable.
Cost and risk of maintenance of
older systems are further exacerbated by a
shortage of suitable maintenance skills; analysts and programmers are not
trained to deal with these systems. Industry wide, it is claimed that 75%-80%
of all operational software was written without the discipline of structured
programming [Coleman 95]. Only a minuscule fraction of current operational systems were built using the object-oriented techniques taught today.
The purpose of this description is to provide a framework or a contextual reference for some of the maintenance and reengineering technologies described in this document.
The operational system lifecycle. The operational environment has its own lifecycle that, while connected to the development lifecycle, has specific and unique characteristics and needs. As shown in Figure 15, a system's total lifecycle is defined as having four major phases:
Each of the phases has typical characteristics and problems. The operational phases are most of the lifecycle and cost. The narrative following describes each phase, and identifies specific technologies in (or planned for) this document that can be applied to correct or improve the situation. In almost every case, taking the proper action in a given phase can eliminate, or greatly reduce, problems in a later phase- at much less cost.

Figure 15: Total System Life Cycle
Terminology. To set a baseline for the descriptions of these phases, the following definitions are used:
Reengineering: rebuilding a piece of software to suit some new purpose (to work on another platform, to switch to another language, to make it more maintainable, etc.); often preceded by reverse engineering. Examination and alteration of a subject system to reconstitute it in a new form. Any activity that improves one's understanding of software, or prepares or improves the software itself for increased maintainability, reusability, or evolvability.
Restructuring: transformation of a program from one representation to another at the same relative abstraction level, usually to simplify or clarify it in some way (e.g., remove GOTOs, increase modularity), while preserving external behavior.
Reverse engineering: the process of analyzing a system's code, documentation, and behavior to identify its current components and their dependencies to extract and create system abstractions and design information. The subject system is not altered; however, additional knowledge about the system is produced. Redocumenting and design recovery are techniques associated with reverse engineering.
Software complexity: some measure of the mental effort required to understand a piece of software.
Software maintainability: some measure of the ease and/or risk of making a change to a piece of software. The measured complexity of the software is often used in quantifying maintainability.
Translation: conversion of a program from one language to another, often as a companion action to restructuring the program.
Phase 1: The development or pre-delivery phase, when the system is not yet operational. Most of the effort in this phase goes into making Version One of the system function. But if total lifecycle costs are to be minimized, planning and preparation for maintenance during the development phase are essential. Most currently operational systems did not receive this attention during development. Several areas should be addressed:
- Requirements traceability to code. Requirements are the
foundation of a system, and one of the most common faults of an operational
system is that the relationship between its requirements and its code cannot
be determined. Recovering this information for a system after it goes
operational is a costly and time-consuming task. See Requirements Tracing, Feature-Based Design Rationale Capture Method for
Requirements Tracing, and Argument-Based Design Rationale Capture Methods for Requirements Tracing for assistance in creating initial mappings from requirements to code.
- Documentation and its usefulness in maintenance. The ostensible purpose of documentation is to aid in understanding what the system does, and (for the maintenance programmer) how the system does it. There is at least anecdotal evidence that
- Classical specification-type documentation is not a good primary source of information for the maintenance programmer looking for a problem's origin, especially since the documentation is frequently inconsistent with the code.
- The most useful maintenance information is derived directly and automatically from the code; examples include structure charts, program flow diagrams, and cross-reference lists. This suggests that tools that create and maintain these documentation forms should be used during development of the code, and delivered with it.
- The complexity of the software. If the software is too complex to
understand when it is first developed, it will only become more complex and
brittle as it is changed. Measuring complexity during code development is
useful for checking code condition, helps in quantifying testing costs, and
aids in forecasting future maintenance costs (see Cyclomatic Complexity, Halstead Complexity Measures, and Maintainability Index Technique for Measuring Program Maintainability).
- The maintainability of the software. This is perhaps the key
issue for the maintainer. The ability to measure a system's maintainability
directly affects the ability to predict future costs and risks. Maintainability Index Technique for Measuring Program Maintainability describes a practical approach to such a measurement, applicable throughout the lifecycle.
Phase 2: The early operational phase, when the delivered system is being maintained and changed to meet new needs and fix problems. Typically the tools and techniques used for maintenance are those that were used to develop the system. In this phase, the following issues are critical:
- Complexity and maintainability must be measured and controlled in
this phase if the major problems of Phase 3 are to be avoided. Ideally, this a
continuation of the same effort that began in Phase 1, and it depends on the
same tools and techniques (see Cyclomatic Complexity, Halstead Complexity Measures, and Maintainability Index Technique for Measuring Program Maintainability). In a preventative maintenance regime, use of these types of measures will help establish guidelines about how much complexity and/or deterioration of maintainability is tolerable. If a critical module becomes too complex under the guidelines, it should be considered for rework before it becomes a problem. Early detection of problems, such as risk due to increasing complexity of a module, is far cheaper than waiting until a serious problem arises.
- A formal release-based maintenance process that suits the environment must be established. This process should always be subject to inspection, and should be revised when it does not meet the need.
- The gathering of cost data must be part of the maintenance process if lifecycle costs are to be understood and controlled. The cost of each change (e.g., person-hours, computer-hours) should be known down to a suitable granularity such as phase within the release (e.g., design, code and unit test, integration testing). Without this detailed cost information, it is very hard to estimate future workload or the cost of a proposed change.
Phase 3: Mature operational phase, in which the system still meets the users' primary needs but is showing signs of age. For example
- The incidence of bugs caused by changes or "day-one errors" (problems that existed at initial code delivery) is rising, and the documentation, especially higher-level specification material, is not trustworthy. Most analyses of changes to the software must be done by investigating the code itself.
- Code "entropy" and complexity are increasing and, even by subjective measures, its maintainability is decreasing.
- New requirements increasingly uncover limitations that were designed into the system.
- Because of employee turnover, the programming staff may no longer be intimately familiar with the code, which increases both the cost of a change and the code's entropy.
- A change may have a ripple effect: Because the true nature of the code is not well known, coupling across modules has increased and made it more likely that a change in one area will affect another area. It may be appropriate to restructure or reengineer selected parts of the system to lessen this problem.
- Testing has become more time-consuming and/or risky because as code complexity increases, test path coverage also increases. It may be appropriate to consider more sophisticated test approaches (see Preventive Maintenance).
- The platform is obsolete: The hardware is not supported by the manufacturer and parts are not readily available; the COTS software is not supported through new releases (or the new releases will not work with the application, and it is too risky to make the application changes needed to align with the COTS software).
At this point, the code has not been rewritten en masse or reverse engineered
to recover design, but the risk and cost of evolution by modification of the
system have increased significantly. The system has become brittle with
age. It may be appropriate to assess the system's condition. Sittenauer
describes a quick methodology for gauging the need for reengineering, and the
entire approach for measuring maintainability
|
[Alberts 76]
|
Alberts, D. "The Economics of Software Quality Assurance." National
Computer Conference. New York, NY, June 7-10, 1976. Montvale, NJ:
American Federation of Information Processing Societies Press, 1976.
|
|
[Boehm 81]
|
Boehm, Barry W. Software Engineering Economics. Englewood Cliffs, NJ:
Prentice-Hall, 1981.
|
|
[Coleman 94]
|
Coleman, Don, et al. "Using Metrics to Evaluate Software System
Maintainability." Computer 27, 8 (August 1994): 44-49.
|
|
[Coleman 95]
|
Coleman, Don; Lowther, Bruce; & Oman, Paul. "The Application of Software
Maintainability Models in Industrial Software Systems." Journal of Systems
Software 29, 1 (April 1995): 3-16.
|
|
[DeMillo 87]
|
DeMillo, R., et al. Software Testing and Evaluation. Menlo Park, CA:
Benjamin/Cummings, 1987.
|
|
[IEEE 83]
|
IEEE Standard Glossary of Software Engineering Terminology. New York,
NY: Institute of Electrical and Electronic Engineers, 1983.
|
|
[Myers 79]
|
Myers, G. The Art of Software Testing. New York, NY: John Wiley and
Sons, 1979.
|
|
[Oman 91]
|
Oman, P.; Hagermeister, J.; & Ash, D. A Definition and Taxonomy for
Software Maintainability (91-08-TR). Moscow, ID: Software Engineering
Test Laboratory, University of Idaho, 1991.
|
|
[Sittenauer 92]
|
Sittenauer, Chris & Olsem, Mike. "Time to Reengineer?" Crosstalk,
Journal of Defense Software Engineering 32 (March 1992): 7-10.
|
|
[Welker 95]
|
Welker, Kurt D. & Oman, Paul W. "Software Maintainability Metrics Models
in Practice." Crosstalk, Journal of Defense Software Engineering 8,
11 (November/December 1995): 19-23.
|