[an error occurred while processing this directive]
Judgement is also difficult because software quality is a complex of values with complex relationships between them. Experience is required in order to build a mental map that captures the relationships.
Finally, judgement of quality is difficult because the different values often conflict with each other, requiring tradeoffs. Experience is required to judge the appropriateness of the tradeoffs that are made.
These roles define the stakeholders in the software. Although the roles may be filled by the same people, the different roles have distinct but overlapping values. The concept of a stakeholder serves a useful purpose in organizing our knowledge of software values. If you can conceptualize a particular kind of stakeholder, it is easier to put yourself in their shoes and recognize the importance of their values.
Aside from the stakeholders described above, there may be other stakeholders that are important to consider. For examples, consider software to manage bank accounts, or software to control radiation treatment machines, or software involved with aircraft flight control. In each case, there are people that are directly affected by the software even though they may be unaware of its existence. The values of these stakeholders are not mentioned explicitly below only because it is difficult to make generalizations. In spite of the difficulties, they must be considered. Due to the possibility of software impact on their lives or property, they can have a major impact on the weighting of the various quality factors.
The value of timely delivery explains why defective software is sometimes successful. Although early software may crash or behave in unexpected ways, purchasers may prefer having software with defects to not having any software.
If there is one operation for each kind of user task then it is easy to perform tasks provided that it is easy to specify an operation. This often depends largely on the ease and naturalness of specifying parameters of operations. For example, in a spreadsheet program, there are many operations that modify the contents of a cell or a block of cells in the spreadsheet. In order to be easy to use, the program must have a good mechanism for designating the target cells.
Even when it is easy to specify the parameters of operations, providing one operation for each kind of task may result in software that is difficult to use because it requires an excessively large number of different operations. Then the user is faced with the hurdle of learning and remembering how to perform the operations. This results in software that has a steep learning curve. Learning is simplified if there are fewer kinds of operations, provided there is an easily understood model of how operations can be combined to perform tasks.
Thus ease of use can be seen to be a composite of two values: ease of performing tasks and ease of learning the operations and their use. Often, one of these values is achieved at the expense of the other, and the best solution may be somewhere between the two extremes.
Regardless of how the set of operations is chosen, ease of learning also depends on the quality of documentation. Many otherwise good programs have failed due to poor documentation. Ease of performing tasks is of little value if inadequate documentation makes learning too difficult.
Many people are involved in the design and programming of a complex program and most will deal with only a few components. The people involved in such a project thus play two roles: they are producers of some components, but they are users of other components. As users, they will evaluate other components in terms of the user values described above. As producers they must be concerned with the primary values of quality in their own product. In addition, they impose their own values.
Good programming languages provide encapsulation mechanisms that aid in achieving data integrity. For example, traditional languages such as C and Pascal have a syntax for defining subprograms with local variables.
Most modern languages also support separate compilation. A separately compiled component can have its own variables, which are accessible by the subprograms in the component but not by subprograms outside of the component. A separately compiled component may also have subprograms that can only be called from within the component. Object-oriented languages such as Java, C++, and smalltalk support encapsulation of data and subprograms for manipulating the data into entities called objects. The effect is similar to separate compilation, but the syntactic mechanisms are more powerful.
It has been estimated that 60% of software development is invoved in maintenance. This makes maintenance a major driving force in the evolution of software development methodology. A software product that is easy to use, works correctly, and runs fast may initially capture a large market, but if it is not easy to adapt and perfect then that market can easily be lost to the competition. Software development firms that expect to survive more than a few years cannot ignore maintenance considerations.
The importance of maintenance has led to values and value concepts that refine the notion of ease of maintenance. The next two values and associated concepts are examples of this.
Cohesiveness is an important concept that is relevant to ease of reuse. A software component is cohesive if it "hangs together" as a single unit; that is, its interface defines a single abstraction. A cohesive software component is more likely to be reusable than a non-cohesive one. If a component performs several unrelated functions the it may need to be broken up in order to be reused. Cohesiveness is also important in the management of complexity, which requires having components that perform complex operations, yet are easy to grasp.
One of the most important features of a high-quality software development process is a strategy for verification. Verification refers to any activity whose purpose is ensuring correct behavior. Verification includes both analytical methods, such as logical analysis and tracing, and empirical methods, such as testing and simulation. In an effective strategy for verification, each component must be verified individually, and interacting groups of components must be verified to ensure that they interact properly.
Ease of maintenance and verification are not only important for components; they are also important considerations for complete programs. Ease of maintenance and verification of programs is dependent on the corresponding qualities of the components, but high quality components are not sufficient to guarantee quality of the program. The components interact as a system and the structure of the interactions has a decisive influence on quality.
Coupling is an important concept that pertains to interactions between components. More precisely, it is a relationship between two components that arises when implementation of one component requires knowledge of the implementation of another component.
Coupling between components can greatly hinder software verification and maintenance, and coupled components are less likely to be reusable. For example, when components are strongly coupled, individual component verification may be impractical or impossible. Then verification of interacting groups must be more thorough to ensure correctness. A strongly coupled group of components is more than the sum of its parts. As a consequence, the difficulty of verifying the group is more than the sum of the difficulties of verifying its parts. This is one reason that coupling is an important term in the vocabulary of software engineering.
Components may have implementation dependence in order to serve an essential purpose. For example, a function for adding entries to a table and a function for removing entries from a table must be dependent since they are working with the same implementation model. On the other hand, clients of a table component should not need to be aware of the implementation. Careful use of encapsulation can and should be used to keep the implementation dependence from arising between a table and its clients.
Evaluation of quality also depends on the level of skill and sophistication of the user. When writing software to aid software developers you can assume that the user can handle a complex interface. Such users are more patient about dealing with a steep learning curve; they are likely to be more concerned with ease of performing tasks than with ease of learning the operations and their use.
Finally, evaluation of quality depends on the technological context. For example, minimal response time and resource usage are of lesser importance today than they were when hardware capabilities were more limited. And as a consequence of the development of more complex software, the importance of ease of reuse, maintenance, and verification has greatly increased.
Judgement is difficult because the ability to understand a value concept does not automatically give you the ability to recognize when it is applicable. For example, you often do not see couplings until you have seen an alternative that avoids them. Also, you might not see problems with ease of use until you have see a better user interface. Finally, you do not see where to apply value concepts until you have gotten into the habit of looking out for them.
Judgement is also difficult because software quality is a network of values with complex relationships between them. The network is initially just a framework for your later understanding. As you acquire experience, you develop the ability to see relationships between the concepts so that you can more comfortably navigate within the framework. Your experience is also recorded within that framework as judgements of what is important and in what contexts is it important.
Finally, judgement of quality is difficult because the different values often conflict with each other, requiring tradeoffs. One common example of a value conflict arises between response time and various other qualities involving program structure. Many inexperienced programmers will corrupt program structure for a small gain in respnse time. More experienced programmers are aware of the consequences: maintenance can get much harder. Timeliness is another value that frequently conflicts with other values. It takes a lot of experience to decide between delivering a flawed product now or a better product later.
[an error occurred while processing this directive]