THE SOFTWARE DESIGN PROCESS
Prof.D.V.Pradeep Sankar HOD/IT
PSREC, IT (2013 2014)
Design when?
Software design ~ activity that turns requirements to a plan or an outline of code When software design takes place varies (size, required quality, e.g., affect). Two opposite ends:
1. 2.
Full detailed spec before anything programmed Design takes place during construction (at the keyboard)
Usually a mix
More often than not, some design in front of a keyboard
Outline
Challenges in Design Design Concepts Heuristics Practices
Challenges in Design
Design is a wicked problem [Rittel, Webber 73]
A
problem that can only be (clearly) defined by solving it
Only after solving it do you understand what the needs actually are
e.g.
Tacoma Narrows bridge
Plan to throw one away Problem of this class
Design
problems are not wicked
Challenges in Design
Process is Sloppy
Mistakes Wrong, dead-end paths Stop when good enough
It is not a bad thing that design is a sloppy activity
Cheap to correct errors when nothing built yet
Goodness of a design dependent on priorities
Fast develoment time? Scalable? High-performance? Adaptable Designers task to strike the right balance
Tradeoffs and Priorities
Priorities can change
Challenges in Design
Restrictions are necessary
Constraints
improve the result Force simplifications and generalizations
Nondeterministic process
Not
one right solution
of thumb vs. fixed process and improve during design, coding
A Heuristic process
Rules
Emergent
Evolve
Brooks: Accidental vs. Essential Difficulties
Accidental difficulties have been and are addressed
Better
languages, better IDEs, better debuggers,
etc.
Essential difficulties unavoidable
Even
with a perfect programming language, software must precisely model parts of real world. This is inherently complex.
Primary goal of software design
Managing Complexity
Managing Complexity
All other goals secondary Goal of minimizing complexity suggests two goals
1.
2.
Minimize the amount of complexity that a human (programmer) must deal with at any one point of time Minimize accidental complexity
Levels of Design
Software system as a whole Division into subsystems/packages Classes within packages Data and routines within classes Internal routine design Work at one level can affect those below and above. Design can be iterated at each level
Key Design Concepts
Most Important: Manage Complexity
Software
already involves conceptual hierarchies, abstraction Goal: minimize how much of a program you have to think about at once Should completely understand the impact of code changes in one area on other areas
Good Design Characteristics
Minimal complexity
Favor simple over clever
Good Design Characteristics
Minimal complexity Ease of maintenance
Imagine what maintainer of code will want to know Be self-explanatory
Good Design Characteristics
Minimal complexity Ease of maintenance Loose coupling
Keep connections between parts of programs minimized
Avoid n2 interactions!
Abstraction, encapsulation, information hiding
Good Design Characteristics
Minimal complexity Ease of maintenance Loose coupling Extensibility
Should be able to add to one part of system without affecting others
Good Design Characteristics
Minimal complexity Ease of maintenance Loose coupling Extensibility Reusability
Design so code could be lifted into a different system Good design, even if never reused
It should be pointed out that the preparation of a library sub-routine requires a considerable amount of work. This is much greater than the effort merely required to code the sub-routine in its simplest possible form. [Whe52]
Good Design Characteristics
Minimal complexity Ease of maintenance Loose coupling Extensibility Reusability High fan-in
For a given class, have it used by many others Indicates reuse effective
Good Design Characteristics
Minimal complexity Ease of maintenance Loose coupling Extensibility Reusability High fan-in Low-to-medium fan-out
Do not use too many other classes Complexity management
Good Design Characteristics
Minimal complexity Ease of maintenance Loose coupling Extensibility Reusability High fan-in Low-to-medium fan-out Portability
Consider what will happen if moved to another environment
Good Design Characteristics
Minimal complexity Ease of maintenance Loose coupling Extensibility Reusability High fan-in Low-to-medium fan-out Portability Leanness
Dont add extra parts Extra code will need to be tested, reviewed in future changes
Good Design Characteristics
Minimal complexity Ease of maintenance Loose coupling Extensibility Reusability High fan-in Low-to-medium fan-out Portability Leanness Stratification
Design so that you dont have to consider beyond the current layer
Good Design Characteristics
Minimal complexity Ease of maintenance Loose coupling Extensibility Reusability High fan-in Low-to-medium fan-out Portability Leanness Stratification Standard Techniques
Use of common approaches make it easier to follow code later Avoid unneeded exotic approaches
Design Heuristics
Rules-of-thumb
Trials
in Trial-and-Error
Understand the Problem Devise a Plan Carry Out the Plan Look Back and Iterate
Find Real-World Objects
Standard Object-Oriented approach Identify objects and their attributes Determine what can be done to each object Determine what each object is allowed to do to other objects Determine the parts of each object that will be visible to other objects (public/private) Define each objects public interface
Form Consistent Abstractions
View concepts in the aggregate
Car rather than engine, body, wheels, etc.
Form base class
Identify common attributes
Focus on interface rather than implementation Form abstractions at all levels
Car, Engine, Piston
Inheritance
Inherit when helpful
When
there are common features
Information Hiding
Interface should reveal little about inner workings
Example: Assign ID numbers
Assignment algorithm could be hidden ID number could be typed
Encapsulate Implementation Details
Do not set interface based on what is easiest to use
Tends to expose too much of interior
Think about What needs to be hidden
More on Information Hiding
Two main advantages
Easier to comprehend complexity Localized effects allow local changes
Issues:
Circular dependencies
A->B->A
Global data (or too-large classes) Performance penalties
Valid, but less important, at least at first
Identify Areas Likely to Change
Anticipate Change
Identify
items that seem likely to change Separate these items into their own class Limit connections to that class, or create interface thats unlikely to change
Examples of main potential problems:
Business Rules, Hardware Dependencies, Input/Output, Nonstandard language features, status variables, difficult design/coding areas
Keep Coupling Loose
Relations to other classes/routines Small Size
Fewer parameters, methods
Visible
Avoid interactions via global variables
Flexible
Do not add unnecessary dependencies e.g. using method that is not unique to the class it belongs to
Kinds of Coupling
Data-parameter (good)
Data passed through parameter lists Primitive data types
Simple-object (good)
Module instantiates that object Object 1 requires Object 2 to pass an Object 3 One object makes use of semantic information about the inner workings of another
Object-parameter (so-so)
Semantic (bad)
Examples of Semantic Coupling
Module 1 passes control flag to Module 2
Can be OK if control flag is typed
Module 2 uses global data that Module 1 modifies Module 2 relies on knowledge that Module 1 calls initialize internally, so it doesnt call it Module 1 passes Object to Module 2, but only initializes the parts of Object it knows Module 2 needs Module 1 passes a Base Object, but Module 2 knows it is actually a Derived Object, so it typecasts and calls methods unique to the derived object
Design Patterns
Design Patterns, by Gang of Four (Gamma, Helm, Johnson, Vlissides) Common software problems and solutions that fall into patterns Provide ready-made abstractions Provide design alternatives Streamline communication among designers
More on Design Patterns
Given common names
e.g.
Bridge builds an interface and an implementation in such a way that either can vary without the other varying
Could go into much more on this
Other Heuristics
Strong Cohesion
All routines support the main purpose
Manage complexity by pushing details away Clearly specify what is needed/provided
Build Hierarchies
Formalize Class Contracts
Assign Responsibilities
Ask what each object should be responsible for
More Heuristics
Design for Test
Consider
how you will test it from the start
Avoid Failure
Think
of ways it could fail should you set values to variables
Choose Binding Time Consciously
When
Make Central Points of Control
Fewer
places to look -> easier changes
More Heuristics
Consider Using Brute Force
Especially
for early iteration Working is better than non-working
Draw Diagrams Keep Design Modular
Black
Boxes
Design Practices (we may return to these)
Iterate Select the best of several attempts Decompose in several different ways Top Down vs. Bottom Up Prototype Collaborate: Have others review your design either formally or informally Design until implementation seems obvious
Balance between Too Much and Not Enough Design documents
Capture Design Work