Software Design

We will use the term "design" quite specifically in this course. It is NOT the same as "development". It is not "anything you do before coding."

Definition: (verb) Design is a problem solving process whose goal is to find and describe a way to implement a system's functional requirements subject to the contraints of the non-functional and other requirements.
Definition: (noun) "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. We need design to create a quality product. Design avoids confusion and errors.

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 software design approaches and history

There are two prominent software design approaches: Functional and Object Oriented

Each has many specific methodologies, but the most prominent are:

The difference between the these two approaches is how they answer this question: "Data or Algorithms, which to design first" Neither approach is superior. Each has advantages and disadvantages, and is more appropriate for certain kinds of problems than others.  It's good to be familiar with both so you can choose the best one for a given situation.

Historically, functional approaches came first.  The reasons are:

OOD is the "new kid" on the block, and it gets a lot of hype.  It solves some of the limitations of the functional approach, but introduces others limitations of its own. 

Design approaches in a nutshell

Functional design is a design approach which considers first what functions a system performs, and postpones consideration of data. It contrasts with OOD, which considers first what data comprise the system, and postpones consideration of its functions.

If you ever wrote a C program as one big main program with all global data, you were doing functional design (but poorly).
 

Functional design process
Object Oriented design process
1. Identify Functions 1. Identify Classes and Attributes
2. Identify Data 2. Identify Operations
3. Establish Hierarchy 3. Establish Visibility
4. Establish Interfaces 4. Establish Interfaces


Know how to choose between OO approach and Functional approach.


Four components of a design

Regardless which approach you take, your finished design must have four components.

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). "Architecture" when used to describe large systems describes the major subsystems and their relationships like client-server or peer-to-peer. When used within a subsystem "architecture" is a class diagram.

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. In OO design, this component is called Class Skeletons. In a large system design, it means a communication protocol.

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,  sequence diagrams, n-s charts.

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.
In a large system, this would include database design.  
 

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:

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:

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
9/25/14 JD  Added a few clarifying notes
2/9/04   JD   Removed paragraph on encapsulation