Maintenance

From Dr. Joey Paquet Web Site
Jump to: navigation, search

After software has been delivered, in whatever form, it must be maintained. Studies support the “80–20 rule”: over the entire lifespan of a software product, 20% of the effort is in development and 80% is in maintenance.

Varieties of Maintenance

The word “maintenance” suggests lubricating your bicycle or taking an applicance to Mr. FixIt to have a part replaced. This kind of maintenance clearly does not apply to software, because code does not get stiff or wear out. Software maintenance is generally divided into four varieties.

Perfective Maintenance improves the system even though it is not failing. The improvements may be internal and invisible to users: for example, a search tree might be replaced by a look-up table to simplify the code without changing performance. Other improvements may be noticeable to users: for example, performance might be improved or short-cut keys provided for frequent operations.

Adaptive Maintenance is concerned with adaptation to changing conditions. If the operating system on which the system runs is upgraded, the system may not work at all or may need to be modified to take advantages of the new OS. In either case, maintenance is required even though there is nothing wrong with the system itself.

Corrective Maintenance responds to faults. When the system fails, maintenance programmers determine the cause of the fault, decide on a strategy for correcting it, and make the correction.

Preventive Maintenance is concerned with preventing failures before they occur. The maintenance programmers may notice weak spots in the code that might cause faults. Preventive maintenance is often carried out in conjunction with corrective maintenance: while correcting a fault, the maintenance programmers examine the code for similar faults and change it to avoid them.

The varieties are listed approximately in order of importance. According to one large study, the relative times spent on these activities are:

activity  % of maintenance effort
Perfective maintenance 50
Adaptive maintenance 25
Corrective maintenance 21
Preventive maintenance 4

The Maintenance Team

After the suppliers have delivered a product, it is essential that they devote some resources to maintaining it. The maintenance team can be of any size from one person to thousands of people. Responsibilities of the maintenance team include:

  • understanding the software;
  • becoming familiar with the system documentation;
  • answering questions about the way in which the system works (or is supposed to work); * analysing faults and problems;
  • locating the cause of faults in the code and correcting the code;
  • keeping system documentation up to date (changes to code imply changes to documents);
  • restructuring design documents and the corresponding code;
  • deleting parts of documents and code that are no longer used;
  • adapting existing functions to changing requirements;
  • adding new functions;
  • managing change.

There are many problems associated with maintenance. Here are brief discussions of a few of them.

Understanding the Software. One study showed that 47% of maintenance programmers’ time is spent in understanding the software. This is a natural consequence of several factors:

  • Most developers keep their “best” programmers for development, considering them too important for maintenance. Consequently, maintenance programmers are usually not top calibre.
  • Newly-hired programmers are often given maintenance tasks before they are allowed to work on development.
  • Developers are closely associated with the software for a long time and come to know it well. Maintainers may be given a component with a problem and told to “fix it”. It may take them a long time to become familar with the overall structure of the system

Management. There is usually a lot of pressure from managers to get faults repaired rapidly to please the client. Conscientious programmers who spend a lot of time analysing and trying to understand the fault receive less praise than sloppy programmers who find a “quick fix”. As the quick fixes accumulate, the software becomes harder to understand and repair. The short-term policy of rapid repair has the long-term consequence of software that is “brittle” — it is poorly structured and breaks under the slightest strain.

Morale. Maintenance programmers often have a lower status than developers. This is unjustified because maintenance programming is in some ways harder than development programming. Nevertheless, the perception that the maintainers are “second tier” programmers is common and has the effect that every maintainer wants to be “promoted” to development.

The morale program can be handled by a good manager who treats all programmers as equals and who requires everyone to take turns at development and maintenance. This approach has the added advantage that doing maintenance gives the development programmers a better understanding of the importance of clarity, simple solutions, and good documentation.

Longevity. The long life of software creates maintenance problems. A large system may be used for 20 years or more. Moore’s Law says that hardware performance doubles about every 18 months. During the 20–year lifespan of the software, the hardware that it runs on can be expected to improve by a factor of 2^{20/1.5} ≈ 10 000. Design decisions that seemed reasonable during the initial development phase may look stupid in the light of such improvements.

The classic example of a longevity problem was the much-exaggerated “Y2K” problem, introduced by the decision to assign two digits rather than four digits to the “year” field in many programs. Performance, however, was not the major factor in the Y2K problem. The decision to use two digits for the year was not made because memory was expensive but because it simply did not occur to the designers that their code would still be running in 1999.

Managing Change. The maintenance team must know, at all times, the exact status of each component of the system. Each time there is a change request for any component, the some or all of the following information should be recorded.

  • Synchronization: when is the change to be made? Identification: who will make the change?
  • Naming: what components of the system are affected?
  • Authorization: who gave permission for the change to be made?
  • Cancellation: who can cancel the change request?
  • Routing: who will be informed of the change?
  • Delegation: who is responsible for the change after it has been made?
  • Valuation: what is the priority of the change?
  • Authentication: (after the change has been made) was the change made correctly?

Software Rejuvenation

The traditional approach to maintenance is that you maintain the system until it becomes unaminatainable — that is, the cost of keeping it running exceeds the benefit of running it. At this time, the system is scrapped and either rewritten from scratch or replaced by a new system designed to different requirements.

A more modern approach is to attempt to rejuvenate the software. If rejuvenation succeeds, the system becomes easier to maintain and its useful life can be extended. There are various approaches to rejuvenation, some simple and others more drastic.

Redocumentation: the system is analysed thoroughly and a new set of documents describing it is prepared. This does not improve the software in itself, but may make other forms of rejuventation feasible.

Reverse Engineering: the current design of the system is inferred from its code. This may be necessary either because the original design documents have been lost or because the design has changed as a result of extensive maintenance. Software tools for reverse engineering exist.

Reengineering: involves both reverse and “forward” engineering, first to discover how the system works and then to improve its structure without changing its functionality.

Code restructuring: the code is modified in various ways to simplify maintenance. For example, very old FORTRAN programs are structured primarily with IF/GOTO statements because FORTRAN did not have WHILE/DO and IF/THEN/ELSE statements. The code can be rewritten using the modern statements, either manually or (better) automatically.

Refactoring: the code is modified as in restructuring, but the changes tend to be larger. For example, related components may be merged, or functionality may be moved from one component to another, more appropriate, component.

Paradigm Change: structured code may be rewritten in an object oriented way, or procedural code may be rewritten in a purely functional way.