Factors Affecting Software Quality
Notes from Chapter 1, Object Oriented Software Construction By Bertrand Meyer
All credits for the below to Bertrand Meyer, this is just my personal notes, which are 90%+ copied word by word from his textbook Object Oriented Software Construction.
Software quality can be described as a combination of external factors such as speed or ease of use which can be detected by users and internal factors such as readable and modular code which can only be detected by computer professionals who have access to the source code.
Whilst only external factors ultimately matter, they can only be achieved if internal indicators of quality exist in the program. However, in this article, we focus primarily on the external attributes of quality.
External Factors of Software Quality
Below are the main external factors of software quality. Object oriented design directly addresses the safety-related factors correctness and robustness, together known as reliability, and the factors requiring more decentralized software architectures: reusability and extendibility, together known as modularity.
Correctness
Correctness is the ability of software products to perform their exact tasks, as defined by their specification. To achieve completeness requires being able to specify the system requirements in a precise form.
Since software systems are complex, methods for ensuring correctness will be conditional in the sense we assume prior layers of code (e.g. an operating system or compiler) are correct and can be relied upon. That said, we should ensure libraries are correct, and separately, the application is correct assuming the libraries are.
Robustness
Robustness is the ability of software systems to react appropriately to abnormal conditions. It complements correctness in the sense correctness addresses the behaviour of a system in cases covered by its specification, whilst robustness characterises what happens outside of that specification.
Robustness is an ambiguous concept, but the role of the robustness requirement is that if abnormal cases do arise, the system does not cause catastrophic events, produces appropriate error messages and terminates execution cleanly.
Reliability is a general term that covers both correctness and robustness.
Extendibility
Extendibility is the ease of adapting software products to changes of specification. Two principles are essential for improving extendibility:
- Design simplicity — a simple architecture will always be easier to adapt to changes than a complex on
- Decentralisation — the more independent the modules, the higher likelihood that a simple change will affect just one module or a small number of modules rather than the whole system
The object-oriented method is, before anything else, a system architecture method which helps designers produce systems whose structure remains both simple (even for large systems) and decentralised.
Reusability
Reusability is the ability of software elements to serve for the construction of many different applications. Reusability reduces the amount of code to be written, which allows one to spend more time testing the quality of each module and thinking about other aspects of quality. It also reduces the overall size of the codebase, making it easier to read and understand (and adapt).
The term modularity covers both reusability and extendiblity.
Compatibility
Compatibility is the ease of combining software elements with others. An example of incompatibility is the wide variety of incompatible file formats supported by many operating systems.
Efficiency
Efficiency is the ability of a software system to place as few demands as possible on hardware resources, such as processor time, space occupied in internal and external memories, bandwidth used in communication devices.
Portability
Portability is the ease of transferring software products to various hardware and software environments.
Ease of Use
Ease of use is the ease with which people of various backgrounds and qualifications can learn to use software products and apply them to solve problems. It also covers the ease of installation, operation and monitoring. One of the challenges is how to provide ease of use for a variety of backgrounds (novices to experts, those who prefer graphical interfaces to those who prefer text-based interfaces and so forth).
Do not pretend you know the user; you don’t. Good designers try to make as limited assumptions about their users as they can. This allows software to outgrow their initial user community and be adapted by a larger audience.
Functionality
Functionality is the extent of possibilities provided by a system. Feature creep is a combination of two problems:
- Loss of consistency and increase in complexity from the addition of new features, affecting its ease of use. The solution here is to work again and again on the consistency of the overall product, trying to make everything fit into a general mold. A good software product is based on a small number of powerful ideas; even if it has many specialized features, they should all be explainable as consequences of these basic concepts. The “grand plan” must be visible, and everything should have its place in it.
- Being too focused on features as to forget other qualities or delay the project too much.
Timeliness
Timeliness is the ability of a software system to be released when or before its users want it. A great software product that appears too late might miss its target altogether.
Other Qualities
Other qualities include
- Verifiability is the ease of preparing acceptance procedures and test data and procedures for detecting failures and tracing them to errors during the validation and operation phases
- Integrity is the ability of software systems to protect their various components (programs, data) against unauthorised access and modification
- Repairability is the ability to facilitate the repair of defects
- Economy, the companion of timeliness, is the ability of a system to be completed on or below its assigned budget
Documentation
Documentation is an essential software quality factor. We may distinguish between three kinds of documentation:
- The need for external documentation, which enables users to understand the power of a system and use it conveniently, is a consequence of the definition of ease of use.
- The need for internal documentation, which enables software developers to understand the structure and implementation of a system, is a consequence of the extendibility requirement.
- The need for module interface documentation, enabling software developers to understand the functions provided by a module without having to understand its implementation, is a consequence of the reusability requirement. It also follows from extendibility, as module interface documentation makes it possible to determine whether a certain change need affect a certain module.
Rather than treating documentation as a product separate from the software proper, it is preferable to make the software as self-documenting as possible. This applies to all three kinds of documentation:
- By including on-line “help” facilities and adhering to clear and consistent user interface conventions, you alleviate the task of the authors of user manuals and other forms of external documentation.
- A good implementation language will remove much of the need for internal documentation if it favors clarity and structure. This will be one of the major requirements on the object-oriented notation used in a project
- The notation will support information hiding and other techniques (such as assertions) for separating the interface of modules from their implementation. It is then possible to use tools to produce module interface documentation automatically from module texts.
Tradeoffs
The factors of quality will often conflict with each other. Often we make the tradeoff decisions implicitly, however a true software engineering approach implies an effort to state the criteria clearly and make the choices consciously.
An Example of the Benefit of Modularity
To finish this article, consider the situation of changing the system of postcodes used by a postal service. This would require altering the physical structure of data, which can have numerous impacts on the rest of the program, which rely on that structure.
- The issue is not that some part of the program knows the physical structure of data: this is inevitable since the data must eventually be accessed for internal handling.
- But with traditional design techniques this knowledge is spread out over too many parts of the system, causing unjustifiably large program changes if some of the physical structure changes — as it inevitably will.
- In other words, if postal codes go from five to nine digits, or dates require one more digit, it is reasonable to expect that a program manipulating the codes or the dates will need to be adapted; what is not acceptable is to have the knowledge of the exact length of the data plastered all across the program, so that changing that length will cause program changes of a magnitude out of proportion with the conceptual size of the specification change.
The theory of abstract data types will provide the key to this problem, by allowing programs to access data by external properties rather than physical implementation.