9.8 Maintainability

9.8 Maintainability

The term "maintainability" has been widely used in the software engineering literature. It is clear from this discussion that maintainability is certainly a desirable property for a system to have. The main problem with maintainability is that no one really knows what it means. As a result, it is a difficult term to quantify. In the past, many people thought that the number of comment statements in code were somehow related to maintainability although there were no scientific studies to support this conclusion. Alternatively, the amount of documentation (presumably measured in kilograms) that a program had was supposed to relate directly to maintainability although, again, there were no scientific studies to this effect.

There are really three different aspects of software maintenance: adaptive, corrective, and perfective. [2] In the case of adaptive maintenance, the code base will change because the requirements, functional or operational, have changed. In the case of corrective maintenance, the code or requirements change because they were not the correct ones. The simplest case is where the code does not implement the module specification. In the case where the requirement is at fault, then the corrective maintenance problem means that the change might propagate from an operational requirement to one or more functional requirements, to multiple module specifications, and thence to a host of code modules. Finally, there is perfective maintenance. In this case the operational requirements and functional requirements are adequate but that certain nonfunctional system requirements such as performance can be enhanced. This will likely occur through a change in an algorithm in one or more module specifications.

We would like to be able to quantify the term "maintainability." It is clear that a system will have good maintainability if we can perform adaptive, corrective, and perfective updates to the system with a minimum of human effort. We can take a cue from modern engineering practice in this regard. A modern office building has a vast complex of blueprints that describe how its various systems are laid out. Good building maintenance discipline suggests that anytime there is a change in any of the subsystems, the blueprints will be modified to reflect the changes that have been made. The larger the building, the more complex the maintenance task. Regardless of how large and complex the building might be, future maintenance efforts are mitigated by maintaining the precise mapping between the building blueprints and the building as it currently exists.

With the mapping of operations to functionalities to modules, it is clear that we can know which modules are used to implement each functionality and each operation. Should we need to change either an operational requirement or a functional specification, we can know which modules will be impacted with this change. Similarly, if a code module does not function appropriately, we can know which functional or operational specifications are linked to that code module. In this context, each source code module can be linked directly to a single design module specification. Further, each data declaration in the source code module is linked to a data description in the design module. We can also insist that each source code statement be linked to a particular statement or element in the design module algorithm pseudo-code.

With the configuration control for the design specification as discussed in Section 9.6, it is now possible to identify and quantify the attributes of software maintainability. These are listed in Exhibit 21.

Exhibit 21: Maintainability Attributes

start example
  • Requirements traceability

  • Number of system operational specifications

  • Number of system functional specifications

  • Number of system module specifications

  • Operation to functionality mapping

  • Functionality to module mapping

  • Number of arcs in the call graph

  • Average number of arcs in module flowgraphs

  • Average number of nodes in module flowgraphs

end example

The question of operational granularity always arises. It is clearly possible to define a system with one operation implemented with one functionality implemented by one huge design module, in turn implemented by one huge FORTRAN main program. Life is full of trade-offs. The greater the granularity of the operational definition of the system, the more complex the average module flowgraphs become. Granularity of specification is not really the issue that it might seem. Quite simply, specifications should be parsed until they can be parsed no further. At the lowest level, the module, parsing a module into two components will certainly decrease the flow-graph complexity of the module. It will also increase the coupling complexity of that module.

9.8.1 Requirements Traceability

The foundation of requirements traceability is that every attribute of a source code module can be mapped to a specific requirement. Furthermore, each operational requirement can be mapped directly to a set of source code modules. In that we have to start somewhere, we will first look at the mapping from the source code module to the design.

  1. Every variable in a source code module is defined in the low-level design module with a variable declaration.

  2. Every statement in the source code module has a pseudo-code equivalent in the module specification.

  3. Every called module in the source code module is listed in the Call_Section of the module specification.

  4. Some elements of the module design specification are not obvious from the source code. Every module that can call a module is listed in the Call_Section of the module specification.

Next, we will turn our attention to the mapping at the functional level.

  1. Every design module specification will be referenced by at least one system functional specification.

  2. That reference will contain the most current version of the design module specification.

  3. Every system functional specification will reference at least one operational specification.

  4. The reference to each operational specification will contain the most current version number.

At the level of the system operational specification, we would like to ensure that the links are in place for the mapping to the system functional specifications.

  1. Every system operational specification will reference at least one functional specification.

  2. The reference to each functional specification will contain the most current version number.

It will not be possible to measure the completeness of the traceability mapping from operations to modules or modules to operations. Sometimes, missing links are made visible through the evolution process when code modules appear that are not traceable to operational specifications or operational specifications that have no associated code modules.

9.8.2 Operational Specification

A very simple system will have but one operation in it. Most logically, this operation would probably read something like this: STOP. Every other system that we might conceive will be more complex than this one. A simple count of the number of user operations is a good leading indicator of the maintainability of a system. That is, maintainability is inversely related to the number of operations that the system can perform.

9.8.3 Functional Specification

Each operation must have at least one functionality associated with it. In most cases, there will probably be many functionalities associated with each operation. Thus, as the operational complexity increases, so too will the functional complexity of the maintenance task. It is clear, then, that the maintainability of a system is also inversely related to the number of functionalities required to implement the set of operations.

9.8.4 Module Specification

Each functionality must have at least one module specification associated with it. Again, there will probably be many modules associated with each functionality. Thus, as the operational complexity increases, so too will the functional complexity, which will also cause an attendant increase of module complexity and, hence, of the maintenance task. It is clear, then, that the maintainability of a system is also inversely related to the number of modules required to implement the set of functionalities.

9.8.5 First-Order Mapping

There are really two levels of first-order mapping between operations and modules: (1) the mappings of operations to functionalities, and (2) the mapping of functionalities to modules. We can represent each operation, functionality, and module as one node in a graph. Each node in the set of operations is connected by an arc to at least one node in the set of functionality; this is a first-order mapping. Similarly, each functionality is similarly connected by an arc to at least one module.

In the most simple case, each operation with be implemented with exactly one functionality and that functionality will be implemented with precisely one module. In this case, for a system of n operations, there will be 2n nodes in the first-order mapping from operations to functionalities and n arcs between these nodes. As the system becomes more complex, there will be an increase in the complexity of the connections between the operations and functionalities. This will no longer be a simple one-to-one connection and there will be m>n arcs in the graph. When m is substantially greater than n, it is clear that the complexity of the relationship between operations and functionalities has risen. Anytime a functionality is modified, this change will impact more than one operation. Hence, m is a good indicator of this maintainability attribute. Again, the maintainability of the system is inversely related to m.

Exactly the same argument can be made for the first -order mapping of functionalities to modules. If there are n functionalities, then the simplest mapping to modules will lead to n modules. If there are more modules, say k, than functionalities, then there must be at least k arcs connecting these two sets. As the relationship between the set of functionalities and modules increases in complexity, the number of arcs will also increase. Let l represent this new value of arcs where l > k. This new value l representing the number of arcs is also a measure of the maintainability of the system. Maintainability is inversely related to l as well.

9.8.6 Second-Order Mapping

There is also a second-order mapping of operations to modules. We can characterize this relationship with a graph of n1 operations, n2 functionalities, and n3 modules, for a total of N = n1 +n2 + n3 nodes. Connecting the sets of operations and functionalities, there are m1 arcs. Connecting the sets of functionalities and modules there are m2 arcs, for a total of M = m1 + m2 arcs. Intuitively, the maintainability of the complete system will be inversely proportional to both N and M.

9.8.7 Call Graph Structure

As the structure of a program becomes more complex, the modules interact to an increasing extent with one another. This interaction can be represented through a call graph as discussed in Chapter 5. The simplest call graph of a software system composed of n modules will have n nodes and n-1 arcs connecting them. There will be but one main program module and one leaf node module in this graph. All other nodes will have one entering edge and one exiting edge. From the standpoint of intramodule complexity, this is the most simple call graph structure, the most easily understood, and, thus, the most maintainable. The complexity of the call graph can only get worse. The number of nodes in this call graph is fixed. The number of arcs is not. If c represents the actual number of arcs in the flowgraph, where c > n-1, then the call graph maintainability attribute is inversely proportional to c.

9.8.8 Module Flowgraph Structure

As previously discussed for a problem of fixed computational complexity, there is a trade-off between the modularity of the implementation of the problem and the internal flowgraph complexity of the module. That is, we can build a program with but one very complex module or we can have a program with a lot of very simple modules with regard to their internal structure. A module with a very bushy control flowgraph will be very difficult to maintain. This complexity was represented by the number of Nodes, Edges, and Paths and in the flowgraph representation of the program module. It is clear that these values are, in a sense, complementary to the call graph values. They are inversely related.

9.8.9 Measuring Maintainability Attributes

There are clearly several distinct maintainability attributes. The above list is probably not at all exhaustive. What we have done, however, is to define maintainability attributes that can be measured. That is the first step in understanding the nature of the maintainability beast. We should be wise enough at this point to know that we cannot simply add the maintainability attribute values together to compute some arbitrary maintainability index. Each attribute has its own measure. These attribute domains are, in fact, potential dependent variables in the modeling process that we will engage in to understand how maintainability might be related to other software quality attributes.

[2]Pigoski, T.M., Practical Software Maintenance, John Wiley & Sons, New York, 1997.



Software Engineering Measurement
Software Engineering Measurement
ISBN: 0849315034
EAN: 2147483647
Year: 2003
Pages: 139

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net