The goal of software engineering is, of course, to design and develop better software. However, what exactly does "better software" mean? In order to answer this question, this lesson introduces some common software quality characteristics. Six of the most important quality characteristics are maintainability, correctness, reusability, reliability, portability, and efficiency.

Maintainability is "the ease with which changes can be made to satisfy new requirements or to correct deficiencies" [Balci 1997]. Well designed software should be flexible enough to accommodate future changes that will be needed as new requirements come to light. Since maintenance accounts for nearly 70% of the cost of the software life cycle [Schach 1999], the importance of this quality characteristic cannot be overemphasized. Quite often the programmer responsible for writing a section of code is not the one who must maintain it. For this reason, the quality of the software documentation significantly affects the maintainability of the software product.

Correctness is "the degree with which software adheres to its specified requirements" [Balci 1997]. At the start of the software life cycle, the requirements for the software are determined and formalized in the requirements specification document. Well designed software should meet all the stated requirements. While it might seem obvious that software should be correct, the reality is that this characteristic is one of the hardest to assess. Because of the tremendous complexity of software products, it is impossible to perform exhaustive execution-based testing to insure that no errors will occur when the software is run. Also, it is important to remember that some products of the software life cycle such as the design specification cannot be "executed" for testing. Instead, these products must be tested with various other techniques such as formal proofs, inspections, and walkthroughs.

Reusability is "the ease with which software can be reused in developing other software" [Balci 1997]. By reusing existing software, developers can create more complex software in a shorter amount of time. Reuse is already a common technique employed in other engineering disciplines. For example, when a house is constructed, the trusses which support the roof are typically purchased preassembled. Unless a special design is needed, the architect will not bother to design a new truss for the house. Instead, he or she will simply reuse an existing design that has proven itself to be reliable. In much the same way, software can be designed to accommodate reuse in many situations. A simple example of software reuse could be the development of an efficient sorting routine that can be incorporated in many future applications.

Reliability is "the frequency and criticality of software failure, where failure is an unacceptable effect or behavior occurring under permissible operating conditions" [Balci 1997]. The frequency of software failure is measured by the average time between failures. The criticality of software failure is measured by the average time required for repair. Ideally, software engineers want their products to fail as little as possible (i.e., demonstrate high correctness) and be as easy as possible to fix (i.e., demonstrate good maintainability). For some real-time systems such as air traffic control or heart monitors, reliability becomes the most important software quality characteristic. However, it would be difficult to imagine a highly reliable system that did not also demonstrate high correctness and good maintainability.

Portability is "the ease with which software can be used on computer configurations other than its current one" [Balci 1997]. Porting software to other computer configurations is important for several reasons. First, "good software products can have a life of 15 years or more, whereas hardware is frequently changed at least every 4 or 5 years. Thus good software can be implemented, over its lifetime, on three or more different hardware configurations" [Schach 1999]. Second, porting software to a new computer configuration may be less expensive than developing analogous software from scratch. Third, the sales of "shrink-wrapped software" can be increased because a greater market for the software is available.

Efficiency is "the degree with which software fulfills its purpose without waste of resources" [Balci 1997]. Efficiency is really a multifaceted quality characteristic and must be assessed with respect to a particular resource such as execution time or storage space. One measure of efficiency is the speed of a program's execution. Another measure is the amount of storage space the program requires for execution. Often these two measures are inversely related, that is, increasing the execution efficiency causes a decrease in the space efficiency. This relationship is known as the space-time tradeoff. When it is not possible to design a software product with efficiency in every aspect, the most important resources of the software are given priority.

The table below summarizes each of the six quality characteristics. With these characteristics, the answer to the question "What is better software?" becomes much more precise. Using these characteristics, software engineers can assess software products for strengths and weaknesses. In addition, these quality characteristics can also be used to compare and contrast the relative merits of software development paradigms. In this case, software engineers do not refer to the paradigm itself as reliable or portable. Instead, they refer to the software products developed with the paradigm as more reliable or more portable than products developed with another paradigm. The two most prominent software development paradigms are the classical or procedural paradigm and the object oriented paradigm.


Maintainability
The ease with which changes can be made to satisfy new requirements or to correct deficiencies.

Correctness
The degree with which software adheres to its specified requirements.

Reusability
The ease with which software can be reused in developing other software.

Reliability
The frequency and criticality of software failure, where failure is an unacceptable effect or behavior occurring under permissible operating conditions.

Portability
The ease with which software can be used on computer configurations other than its current one.

Efficiency
The degree with which software fulfills its purpose without waste of resources.

References