Clearly Specifying Quality
One of the most difficult things to do in software development (if observation of projects across the industry is any indication) is clearly specifying the system needs from the quality perspective. Functional specifications are often incorrectly labeled as the complete specification for the system, or attempts at specifying the quality side degrade to untestable statements such as “The system shall be user-friendly.” Worse yet, attempts to simply reuse quality specifications from existing systems can result in serious consequences from under-specification, or unachievable goals from over-specification of quality.
Without capturing the quality attributes (or non-functional requirements) at the same level as the functional requirements, several problems arise. While all features may have been developed, it will still be unclear whether the system is ‘good enough’. Also, without an understanding of the quality demands of the system up front, you cannot identify the appropriate elements that need to be constructed to achieve these goals: test harnesses, development standards, or internal mechanisms that create a sufficiently robust system.
There are good, clear taxonomies of quality attributes to use as a starting point (typically identifying individual elements such as testability, usability, maintainability, and a host of others). These are inadequate by themselves in that it is difficult or impossible to specify in an unambiguous (preferably quantified) fashion, and they are often at odds with one another as well. No system can be developed that will completely satisfy the breadth of all attributes.
As with any difficult problem, the solution lies in a divide-and-conquer approach. First, eliminate any attributes from the taxonomy that clearly don’t apply. A stand-alone, one-off utility on a single operating system is not concerned with reusability, interoperability or maintainability, for example. The more you can eliminate here, the easier life gets later.
Second, prioritize the remaining attributes. This can be done by comparing them in a pair-wise Boolean manner or some other fashion, but the key point here is to be ruthless – it is important to identify the few attributes that are critical to the system, and ensure that these are adequately addressed.
Third, identify criteria that will allow you to address the important attributes in a quantified fashion. Identified limits on code complexity or module length, specific coding standards, identified peer review criteria, and traceability expectations are all items that can be specified to improve the maintainability of the system. Well chosen criteria will address several of your most important attributes simultaneously.
Finally, capture all these specific criteria, in clear, testable form, in the requirements specification alongside the functional requirements.
Doing this will not guarantee a high quality system, but failure to do so will almost certainly guarantee the lack of a high quality system, or at least one that has required an inordinate amount of time and resources to build. Clearly specifying quality attributes is one of the highest leverage activities you can perform in the early stages of any project. – JB