We begin by describing the nature of engineering in general, including
how it relates to:
- Crafts, and
- Sciences, including computer science
Next, we describe software engineering in particular, noting how
the nature of software itself makes software engineering unique.
Engineering has its roots in two important human activities: crafts
and sciences.
This section describes the nature of these activities and how
engineering in general relates to them.
Understanding what it means to be a craft will require the following
foundational concepts:
- Values
- Knowledge
- Quantification
- Creativity
A craft is concerned with the creation, and possibly the maintenance,
of a type of
product, that is produced for its
value,
which can be of two types:
- Aesthetic: The product is valued as an end in itself, or
- Utilitarian: The product is a means to another end
In either case, practicing a craft requires a knowledge of values and the
means for achieving them.
Practicing a craft requires two kinds of knowledge:
Practice is needed to develop habits in the use of the tools and
techniques.
These habits partially automate the achievement of value, freeing the
mind to deal with more complex issues that may arise.
The knowledge of values together with the practiced habits make up the
work ethics of a craft.
Quantification — the use of numeric or symbolic abstractions
— may be essential in the construction of a finished product:
- Quantification of physical properties (e.g. temperature) of raw materials
- Quantification of design models (e.g. musical notation)
A full-blown mathematical theory may or may not be needed.
Practicing a craft is a creative effort, and it takes imagination to:
- Put raw materials together in new ways to
create a product of value.
- Use tools and techniques in new ways to
enhance the value of the product.
Creativity is an important quality that distingushes expert practitioners from
average practitioners.
In the early stages of development of a craft, understanding
how things
behave is of primary importance; understanding
why is of secondary
importance.
Scientific understanding also begins with an understanding of how things behave,
but a science ultimately focuses more on why they behave as they
do.
With more complex products and production processes, just knowing how
things behave is not sufficient;
There is also an increased need for understanding causal relationships —
the answers to "why" questions.
The answers to these questions often have predictive power that is
essential for developing new techniques and methodologies of product design and
production.
When the causal knowledge about the behavior of the product and its constituents
is well-developed in a craft it becomes a science.
The human mind does not deal well with a large, unorganized collection of facts.
In order to serve human needs, related facts must be organized into a
theory, with a single theory encompassing and explaining a large
number of facts.
A science is a body of causal knowledge about a subject matter,
organized into theories.
Theories provide explanations of relationships between
characteristics of objects covered by the subject matter and the
behavior of those objects.
In some areas of science, this understanding can be used to predict
behavior, leading to a utilitarian value for science
— applied science.
However, a well developed science has a core which is concerned with
understanding for its own sake — pure science.
Most sciences attempt a quantification of the relevent concepts if it is
practical.
In some well-developed sciences, such as physics and chemistry, the
quantification plays a central role, resulting in a mathematical
theory or model
at the heart of the science.
In some areas of science, such as evolutionary theory in biology,
measurement is not always practical and the mathematical theory is not
very well developed.
Practicing a science is a creative effort. It takes imagination to:
- Put facts together in a way that makes sense
- Develop concepts that have explanatory power
Creativity is an important quality that distinguishes expert scientists
from average scientists.
Pure scientific values have to do with the quality of, not products,
but scientific thinking itself:
- Correctness of scientific inference
- Explanatory power
- Simplicity
- Testability
Applied science may involve
producing products with greater functionality or higher quality,
requiring knowledge of the
causal factors that affect its value.
Such causal knowledge involves:
- Factors involved in the quality of a product
- Means for quantifying those factors
- Characteristics that control those factors
- Principles that focus attention on important value-related
product design issues
When a science is concerned with this kind of causal knowledge, it is
an
engineering science.
Computer science is the study of
computational processes:
- How to specify them:
- Formal languages
- Data abstraction
- Procedural abstraction
- How to reason about them:
- Algorithmic efficiency
- Computability
- Complexity
- How to build machines that bring them about:
- Architecture
- Operating Systems
Computer science is both similar to and different than mathematics
and pure science in important ways.
Theoretical computer science, the formal study of
computational structures and computation itself, is mathematical in
nature.
Non-theoretical computer science, concerned with the creation of
software and the machines that run it, can be empirical and
experimental.
In either case, computer science differs from natural science in
that the computational objects it studies are objects of its own
making.
The computational objects CS both creates and studies, as far as
software is concerned, are abstractions.
Mathematics also creates its own subject matter in the form of
abstractions, but there is a crucial difference:
- Mathematical abstractions are inference structures
- Computer science abstractions are interaction patterns
Values in mathematics, like the values of pure science, concern the
quality of mathematical thinking itself:
- Rigor and consistency
- Correctness of inference
- Simplicity and elegance
Values in computer science concern the best ways to create and
control the computational objects they create, whether they are:
- Data structures
- Algorithms
- Programs that implement them
Since creating and controlling computational objects requires
causal knowledge, computer science is best understood as an
engineering science.
Conceptually, engineering disciplines arise from crafts as their
knowledge bases evolve into sciences.
If a craft is producing a utilitarian product then there is a demand
for:
- Greater functionality of the product
- Higher quality in the product
- Greater quantities of the product
Meeting these demands results in more complexity in the product, or in
the production process, or both.
For a craft to become an engineering discipline it must develop a
better understanding of problems involved in planning
and managing the product
development process and the people involved.
Production of complex products, large quantities of products, and
more functional products all require a significant amount
of
planning:
- When the product is complex or the product has
greater functionality, planning focuses on designing the
product.
- When large quantities of a product are produced,
the planning focuses on designing a production process.
- The magnitude of this effort may require that the people involved
develop specialized skills:
- Some continue with the actual production
- Others are involved in the design of products and
production processes.
Planning is part of any engineering discipline.
Production of complex products requires the use of
teams of
engineers to do the design. This requires:
- A well-defined design process.
- A management structure to:
- Guide people through the process
- Identify risks involved
- Allocate necessary resources
- Engineering managers must themselves have an
understanding of the engineering discipline
To prepare engineers to work on and lead teams, management is an
important part of engineering education.
Because software engineering is engineering, it inherits the features
already mentioned about engineering in general.
Software engineering also inherits from computer science as its
mother discipline.
However, software engineering has unique characteristics and problems
owing to the uniqueness of software as a product.
These differences arise primarily in three areas: the nature,
functionality, and maintenance of software.
Software engineering is characterized by its primary product, which is
software — programs that bring about a computational process.
Many of the subject areas of computer science deal with software
products:
- Programming languages
- Implementations of algorithms and data structures
- Systems software
Because of this, the boundary between computer science and software
engineering is sometimes vague; in particular, the values of software
engineering are an important element of computer science.
Whatever the context, the production of large quantities of software
characterizes software engineering.
Software has an inherently
dual nature:
- It is physical:
- Can be handled on physical media such
as hard drives, optical disks, memory sticks
- Runs as electronic processes on a physical processor
- It is abstract:
- Written in formal language
- Describes abstractions such as objects
Due to the dual nature of software, creation of physical products and creation of
software differs:
- The production of large quantities of some physical products (say
automobiles) introduces a great deal of complexity into
the production process.
- The complexity of large pieces of software is in the design
process:
- Deals with abstractions
- Requires large intellectual effort
Reproducing software, even large quantities of copies, is relatively
easy once it has been designed.
Software engineering is concerned almost exclusively with the design of
the product and not the production process.
Besides having a dual nature, software is also unique in the scope of
its application.
The magnitude of this scope has an impact on the software development
process.
Non-software product categories are targeted toward specific uses:
- Transportation
- Shelter
- Entertainment
Software, however, can be applied to the automation of any human task.
In particular, any engineering process can benefit from the support of
software.
Therefore, any engineering process can become, in part, a software
engineering project.
There is no single domain of knowledge that covers the behavior
of all software products.
- There is no single body of theory that tells software
engineering how to specify and measure the behavior of its
products.
- Software engineering has computer science, but:
- Computer science does deal with the components of software and
some of the tools and techniques involved in its
construction
- Computer science does not and cannot deal with all of the
kinds of behavior exhibited by software.
The values of software engineering are driven by customers who
have an unlimited range of needs. As a result,
- Classification of the wide range of values is a virtually impossible
task.
- When values can be identified, they vary considerably in
importance; a value that is unimportant in one software
product may be crucial in another.
For these reasons, the ethical and value-oriented side of software
engineering takes on a more prominent role.
The extensive variety of software functionality and values can be dealt
with by software engineers specializing in a particular domain:
- Software development firms can specialize, for example, in
business and accounting software
- Firms whose main business is not software, for example banks,
can create a department dedicated to software development
Demand for a software product often does not warrant specialized
software development firms or departments.
A second option is that people that are trained in the application area
develop programming skills:
- A workable option for relatively simple
software
- For more complex software, the lack of software
understanding may outweigh the advantage of familiarity with the
application domain.
A more general solution to the problem is to build
domain
analysis into the software development process.
In this approach, a significant amount of time early in development is
devoted to:
- Communicating with experts in the application area, noting
important concepts and their relationships.
- Building a domain model that can be readily converted
into software.
Another important part of the process involves building the product in stages
and getting feedback from the customer about the preliminary versions.
In other engineering disciplines, product maintenance is concerned
with the
deterioration of a product over time.
Software, as an abstraction, does not deteriorate, and can be readily
and cheaply reproduced.
In software engineering, the maintenance objective
is
improving the product.
Software maintenance is perhaps better described as
software
evolution.
There are three general types of software maintenance, defined by the
types of improvements.
- Corrective: modifications that correct defects.
- Perfective: modifications to:
- Add new behavior
- Modify old behavior to make it more suitable to
users
- Modify structure to simplify future maintenance (refactoring).
- Adaptive: modifications that aim towards adaptation for new
or modified platforms.
The low cost of software reproduction and installation makes it
practical to develop software that is continuously upgraded
while in
use.
It has been estimated that
90 percent of the software development effort
is involved with maintenance.
This figure reflects overall effort, including unsuccessful software.
For successful software with a long history, the figure is nearer to
100
percent.
Since so much of successful development effort is involved in
maintenance, the interests of developers weigh heavily in software
values that ease maintenance.
These values include designing for change, documenting design, and
effective and rigorous testing.
The burden of software maintenance is eased for the developer if
software design is structured so that future changes
can be made more easily:
- Minimize the complexity and nature of interactions
between components through decoupling
and cohesion.
- Use architectural and design patterns that
reduce the impact of changes.
The burden of software maintenance is eased
for the developer through
design documentation:
- With a poorly documented design, software maintainers will spend a
lot more time studying the existing software before making
changes.
- Working with undocumented aspects of design are also likely to
introduce new errors.
The burden of software maintenance is eased
for the developer if extra effort is spent in developing
test
software and procedures that can be reused:
- Software engineers routinely engage in a technique
called refactoring: making design changes to software that do not change
its functionality.
- The changes are made for the purpose of simplifying future
maintenance.
- After a refactoring, the original test software can be
reused without modification.
Software engineering can be defined as:
The process of solving
customers' problems through the systematic development and
maintenance (evolution)
of large, high-quality software systems within cost, time, and other
constraints.
This requires:
- Satisfying the software stakeholders, one of
which is the customer
- Implementing the best practices for systematic
development and maintenance of software
- Knowing what it means for software to be of high-quality
- How to trade off cost, time, and other
constraints
Each of these in turn requires knowledge of
software engineering values.