Software Design
Definition: "Design is a meaningful engineering representation of
something
that is to be built."
Example: A blueprint for a house is the classic example of an
architectural
design.
Why do we need design? Imagine trying to build a house without a
blueprint.
- Create a quality product.
- Reduce confusion and
errors.
- Manage complexity
- Improve estimation
- Provide a robust framework
- Facilitate maintenance / enhancement
- Organize the construction effort
Unfortunately, often software development proceeds without adequate
design, using a "house of cards" approach. The result is fragile,
unstable,
inflexible, error prone software.
What you need to know about design:
Design Methods (elaborated)
Software
Architecture and Design Patterns
Design Rationale Documentation
General design approaches and history
There are two prominent design approaches: Functional and Object
Oriented
Each has many specific methodologies, E.g.
- Structured Design (functional)
- UML (object oriented)
Data or Algorithms, which to design first?
- Algorithms (functional)
- Data (object oriented)
Neither approach is superior. Each has advantages and disadvantages,
and
is more appropriate for certain kinds of problems than others.
Historically, functional approaches came first.
- Requirements are stated as functions, so functional design is an
obvious
transition from requirements.
- Computer Architectures are functional, so early languages were
functional,
and lend themselves to functional designs.
Four components of a design
Mnemonic: PAID (Procedural, Architectural, Interface, Data)
"You won't get PAID until your design is complete."
Architectural design defines the structure and relationships
among major elements of the software. The architecture is the framework
of the solution, often comprised of "design patterns." Examples: Class
Diagram, Module hierarchy chart (structure chart).
Interface design describes how the elements of the design
will
communicate with each other. It describes the "protocols" or
"contracts"
that allow elements of the design to request services of each other.
Examples:
C++ header file, Ada spec file, Java interface.
Procedural design describes how the functional aspects of the
software will work. It describes the logic and control structures for
the
operations in the design. It's the algorithms for each element in the
solution.
Examples: pseudocode, flowcharts, interaction diagrams.
Data design describes the data structures which will store
the
information used in the solution.
Usually each component has its own representation or notation, but
sometimes
they are combined.
Design Principles
There are several principles which guide the design process. Three
important
ones are decomposition, abstraction, and information hiding.
Decomposition
Definition: To subdivide a solution into separable components that are
named and addressable.
Decomposition is the primary tool for attacking large problems, by
using
a "Divide and conquer" strategy.
It helps us several ways:
- Allows for distribution of effort via parallel development.
- Makes testing easier by isolating errors
- Promotes reuse.
- Localizes changes for easier maintenance.
- Makes the solution simpler to comprehend
The disadvantage is the cost of integrating all the separate pieces.
Abstraction
Definition: To focus on the significant or essential aspects of a
situation
or problem and ignore irrelevant details. In slang, it's "Don't lose
sight
of the forest because of the trees."
Abstraction is a tool for coping with complexity. If you find
yourself
feeling like there's too many things to keep in your head at once, then
invent an abstraction.
It helps us several ways:
- It simplifies a design by hiding low level details and keeping
the
emphasis
on the main features of the solution.
- It promotes implementation independence, meaning we can
change
the
implementation (low level) without affecting the entire system (at a
high
level).
- It simplifies our thinking by allowing us to focus on the problem
domain
and defer the details of the implementation until later.
Examples: "Sort" is a procedural abstraction, "Stack" is a data
abstraction.
Practice
Exercises
Abstraction and software evolution
Information Hiding
Closely related to abstraction, information hiding refers specifically
to suppressing (or keeping private) the internal details of a program
component.
The internals of a component are inaccessible to other components that
don't have no need for such information. Other components that
wish
to access it must do so via the components public interface.
Information
hiding gives a software design more integrity by controlling access to
the internals of a component.
Thoughtless or sloppy design can defeat the purpose of
information hiding.
Read this example of a design which doesn't
respect
encapsulation.
Document History
2/9/04 JD Removed paragraph on encapsulation