Software engineering values are what every software engineer must
learn to produce
high-quality software.
-
High-quality software is that which meets well-stated
requirements
-
Producing quality software requires
understanding the role and perspectives of the
various stakeholders in software, and the context in
which the software is situated
-
Although software quality is based on concepts that
are not hard to grasp, learning to judge the quality of
software is difficult
and doing it well requires considerable experience
A requirements specification must completely define the tasks that
are to be performed by the program or system, as well as any
constraints that are placed on its development or use.
Requirements are of several kinds:
-
Functional: Determine how users
interact with the software and how the software should behave when
it is used correctly:
-
What inputs the system should accept, and under what
conditions
-
What output the system should produce,
and under what conditions
-
What data the system should store that
users or other systems might retrieve
-
What computations the system will perform
-
Platform: the hardware, operating system,
and technology the software will use
-
Process: development methodology, delivery
date, and cost
-
Quality: the features of the software that provide
its value to its stakeholders.
Software is important to many people, who play a variety of roles with
regard to the software.
Primary stakeholders have direct contact with the production of
software and/or its use:
-
Purchasers of the software
-
Users of the software
-
Developers of the software
-
Managers of the hardware systems on which the
software runs
The purchaser pays for the software and determines its overall
objectives.
If the software is developed under contract then the requirements
specification for the software is negotiated between the purchaser and
the developers.
The primary values for the purchaser are
correctness, reliability, system
data, delivery, and cost.
Software is correct if it meets its requirements specifications.
-
For software that is developed under contract, purchasers and
developers iron out specifications for the software.
-
For "shrink-wrap" software, the specifications are worked out by
developers in anticipation of the needs of the purchasers.
Determination of correctness requires assessment of functional
requirements.
Correct software, of course, is more highly valued.
Reliability as a value acknowledges that products can fail to meet their
specifications.
The value placed on reliability is an adaptation of correctness to the
real world through quantification:
-
In other engineering disciplines, reliability is
often measured by how long products take to fail
-
In software engineering, the concern is with how often
the software fails
Failures can result from flaws in the requirements, design, or code.
Large programs or systems of programs often have the responsibility of
maintaining a permanent body of data.
Such data may be subject to constraints:
-
Integrity, for example, consistency or
non-redundancy
-
Security, for example, for privacy or to limit
modification
Then the software must ensure that it does not violate these
constraints.
The purchaser of software almost always prefers to have it earlier
rather than later, and preferably by a given date and not "R.S.N.":
- When the purchaser is a business firm, it may
need the software by a deadline in order to meet its own
commitments.
- If the purchaser does not receive the software by
a deadline, may decide to turn elsewhere.
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.
- Because of its nature, software has developed a
culture of "beta testing", in which developers rely on
reports from users in order to improve it.
Finally,
the purchaser will want to pay the
smallest price that will
obtain the desired functionality and quality.
Users, who may not be purchasers, interact with the software.
- User needs may determine additional specifications
with regard to the software's user interface.
- Prototypes may be required to work out these
specifications.
For users, software values will center around
correctness, robustness, and ease of use or usability.
Related to these general user values are more specific
principles
of user interface design, which are not discussed here.
Users are also concerned with correctness.
If the software behaves incorrectly it will probably add
significantly to the time that it takes to accomplish a task, or
make the task impossible.
Incorrect software may lead to
user frustration and decrease the
chance of
user acceptance.
Robustness is the ability of software to handle
exceptional conditions.
Robustness is especially important for programs that interact
with human users, since humans make mistakes. For example:
-
Suppose a program prompts the user to enter a number,
and then waits to read the user response.
-
A robust program will be prepared for a
non-numerical response, and
will take appropriate action, such as offering the user another
chance to enter the number.
Programs that crash or attempt to do something meaningless in
exceptional conditions are
brittle and can contribute to
user frustration.
Usability is a familiar concept, but it is not simple.
The usability of software depends on the nature of the
operations
it offers, the
ease of performing user tasks, the
ease of learning the operations, user
documentation, and
system
response time.
Usability is most difficult to analyze for programs that are designed to
aid the user in performing a complex variety of tasks, such as word
processors or spreadsheet programs.
Here the software designer has a spectrum of possible choices:
-
At one end: The operations provided by the program
are the same as the tasks that user wants to perform.
-
At the other: The program only provides primitive
operations — a minimal set of operations that can be
combined to accomplish any of the required tasks.
The first choice is preferable provided that it is easy
to
specify the operations.
The ease of specifying an operation
often depends largely on the ease and naturalness of specifying
parameters of operations. For example,
-
In a spreadsheet program, a user may want to find
the average of a column or row of numbers.
-
In order to be easy to use, the program must have a good mechanism
for parameterizing the average function, i.e. designating the
target cells to be averaged.
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 provides 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 long
learning curve.
Software's ease of use can be seen to be a composite of two values:
- Ease of performing tasks
- Ease of learning operations and their use
Often, one of these values is achieved at the expense of the
other:
- Learning can be simplified if there are fewer kinds of
operations provided by the software, but
- Fewer operations mean that there must be an
easily understood model of how operations can be combined to
perform more complex tasks.
The best solution often lies somewhere between these extremes.
Regardless of what set of operations a piece of software affords,
ease of learning also depends on two aspects of its
documentation:
- Quality:
- Many otherwise good programs have failed due to poor
documentation.
- Modern users often expect documentation
through non-print media such as video tutorials
- Availability:
- Help built-in to the program
- Online help that is more likely to be up-to-date
User documentation is not to be confused with
program
documentation, discussed later.
Response time is the elapsed time between the initiation of an
operation and its completion.
- Excessive response time means that a user will
have to spend more time accomplishing their tasks, so up to a
point there is a need to minimize response times.
- However, once response time has been reduced below the time
required for the user to grasp the results or
initiate another operation, then there
is no gain in further reduction.
System managers oversee the operation of computer systems on which
software must run.
System managers are responsible for installing new software and
making sure that the system provides the resources that the software
requires.
These responsibilities determine their values.
Ease of installation as a value depends on the type of
software:
- Shrink-wrap software:
- The purchaser, user, and system manager are
all the same person.
- Installation should be largely automated
- Considerable effort may be required in the
development of installation software ("wizards")
- Software developed under contract:
- Installation may require a knowledgable software
manager
- Good installation documentation is a must
A program uses various
resources that are available from
the system:
- CPU processing cyles
- Disk space
- Memory
A system manager prefers to see resource usage minimized
in order to avoid higher costs for faster processors or
additional disk space or memory.
Minimizing resource usage may also indirectly benefit the
user since
response time usually suffers when system resources are pushed to
their limits.
Software developers face a difficult task in the production of quality
software.
Programs need to be broken down into components, each specialized to
deal with a limited aspect of the overall functionality of the
program.
A software component is any piece of software that has a clear role,
can be isolated, and therefore replaced. Examples:
- Methods
- Classes
- Packages
- Frameworks
- Beans
- UI Components
Like a person in a complex organization, each component will do some of
the work, but it will call upon other components if the need for their
specialized ability arises.
The values that software developers place on components depends on
the
roles the developers play with regard to software components.
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, often
simultaneously:
- Producing components, creating
them for their own use or the use of other developers
- Using components to create other
components
As users, software developers will evaluate other components in terms
of the user values described previously.
As producers they will impose their own values — values that
set software engineering apart from other disciplines:
- Ease of maintenance
- Ease of verification
- Data efficiency and integrity
- Encapsulation
- Coupling
Many important software components have the responsibility of
maintaining a body of data and providing methods for accessing the
data.
Maintaining data involves several values:
-
Efficiency: A complex organization is often
required to reduce the effort needed to locate a particular data
item.
-
Program correctness and Robustness:
- The data organization must satisfy design
constraints and data consistency conditions.
- May require restricting
the capabilities of other components for modifying the data.
Issues of data consistency and modifiability define the value
of
data integrity, a crucial value in the design of database
management software, operating systems, data structures, and many
other types of components.
Data integrity can be more easily achieved if data and the operations
that can be used on it are kept together, so that changes to the data
are localized.
Good programming languages provide
encapsulation mechanisms
that enforce this:
-
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.
-
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
-
Mechanisms for controlling access are more powerful
The special importance that maintenance
has for software has already been described (see Software
Maintenance at left).
The importance of maintenance has led to values and value concepts
that refine the notion of
ease of maintenance:
The software that is available today could not be produced at a
reasonable cost if each program were constructed from scratch.
Therefore, software's ease of reuse is an important
value.
Software developers employ reuse in two ways:
- By using previously created software in the
creation of new projects
- By designing new software so that it can be
reused for other projects in the future
Reusable software can come in two forms:
- Libraries: code to perform lower-level
functions at the behest of higher-level applications
- Frameworks: higher-level applications
that require individualizing code to be complete
Ease of use is desirable for all components, but it is much more
important and more difficult for components that are intended for
use in a variety of applications, such as frameworks.
A software component has cohesion (or 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 then it may need to be broken up in order to be reused.
- If a component performs several unrelated
functions, one of them it may interfere with a component that
wants to use it.
Cohesive components are easier for developers to understand, so
they aid 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 system correctness.
Verification
types include:
- Analytical (formal) methods, such as logical
analysis and tracing
- Empirical methods, such as testing and
simulation.
Verification
scopes include:
- Verifying each component individually, as
in unit testing
- Verifying whole groups of interacting
components, as in integration testing
Software verification is easier to accomplish when:
- Verification plans are created in advance
- Automated tools and techniques are employed in the
verification process
High quality components are not sufficient to guarantee quality of
the complete program.
The components interact as a system and the structure of the
interactions has a decisive influence on quality.
In order for
values like ease of maintenance and verification to apply to complete
programs, their components must be minimally coupled.
Two components are not coupled simply because they interact. They are coupled when:
- Implementation of one component requires knowledge of the
implementation details of the other, so
- Changing one component entails changing the other
Designing components to interact without being coupled is a
fundamental value of software engineering.
Certain 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.
A strongly coupled group of components is more difficult to work
with, because
- Verification of individual components is
difficult — a strongly coupled group is more than the sum of its
parts
- Verification of interacting groups must be more
thorough to ensure correctness
- Coupled components are less likely to be
reusable
- Coupled components are more difficult to change as
the maintenance demands increase
Although these software developer values are of direct
interest only to software producers, they have indirect, but
significant, effects on other stakeholders.
If software developer values are upheld, other values are likely:
- For purchasers: timely delivery of software and
software upgrades
- For users: overall quality of the software
- For managers: efficient use of resources
In addition, there are countless other people who are directly affected
by software even though they may be unaware of its existence, e.g.:
- Bank customers, because software manages
bank accounts
- Cancer patients, because software controls
radiation treatment machines
- Airline passengers, because software is involved with
aircraft flight control
These are "secondary" only in the sense that their roles are not directly
involved with the production of software and its use.
The software values of these groups are difficult to generalize, but
due to the software impact on their lives or property, they must be
considered by the primary stakeholders.
Evaluation of software quality depends on aspects of the situation in
which it is embedded.
Evaluation of software quality depends on the nature of the
application and the roles of its components. For example:
- If human lives or property depend on a program
then correctness and robustness are of utmost
importance in the program and many of its components.
- If a component is a part of a prototype
then timely delivery assumes a greater importance.
- If it is a part of a real-time system then its
response time may be crucial.
Evaluation of quality also depends on the level of skill and
sophistication of the user.
Three general classes of users:
-
Other software developers:
-
Can handle a complex interface and
occasional failures
-
Worry less about the ease of learning of the software
-
Technically-minded professionals:
-
Are probably familiar with using software routinely
-
Are most concerned with correctness
-
Those who have never used software in their jobs:
-
Expect naivete, with ease of learning
and robustness most important
-
Expect possible hostility, especially if user
worries about software replacing him/her
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.
-
As a consequence of the development of more complex software, the
importance of ease of reuse, maintenance, and verification has
greatly increased.
The values and value concepts presented here are only a
first step towards learning to judge quality.
Although it is easy to grasp the values and value concepts in terms of
their purpose and general nature, a good software engineer spends a
lifetime learning to use them effectively to judge software quality.
Judgment is difficult, first, because the ability to understand a value concept
does not automatically give you the ability to recognize when it is
applicable.
One does not see where to apply value concepts until one has
gotten into the habit of looking out for them. For example:
-
You often do not see couplings until you have seen an
alternative (often in the form of a design pattern) that avoids them
-
You might not see problems with ease of use until you have see a
better user interface
Judgment is also difficult because software quality is a network of
values with complex relationships between them.
The values 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.
An example of the complex relationships among software values
is tradeoffs, where values come in conflict with each other.
Every engineering endeavor involves value tradeoffs, and software
engineering is no different. For example:
-
Response time vs. Encapsulation:
- Many inexperienced programmers will use
global variables for a small gain in response time.
- More experienced programmers are aware of the
consequences: maintenance can get much harder.
-
Timely delivery vs. Correctness:
- It takes a lot of experience to decide between
delivering a flawed product now or a better product later.
-
Data security vs. Ease of use:
- For example, deciding when to time out an idle
banking session