Software Design Principles and Guidelines
Douglas C. Schmidt
[email protected] Vanderbilt University, St. Louis
www.cs.wustl.edu/schmidt/
May 25, 2003
Design Principles
Design Principles and Guidelines Overview
NETWORK STUBS OS KERNEL NETWORK INTERFACE MESSAGE-PASSING MIDDLEWARE HOME MIDDLEWARE SERVICES
(SECURITY,EVENTNOTIFICATION,TRANSACTIONS,PERSISTENCE,LOADBALANCING,
FAULTTOLERANCE,A/VSTREAMING,DYNAMICRESOURCEMANAGEMENT,SCHEDULING,
NAMING,TRADING,LOGGING,ETC...)
CALL BACKS CONTAINER operation() MIDDLEWARE INTERFACE OBJECT ADAPTER CLIENT OS KERNEL NETWORK INTERFACE COMPONENT EXECUTOR SKELETONS NETWORK
PROTOCOLS PROTOCOLSNETWORK
Design Principles
– Important design concepts – Useful design principles
Development Methodologies
– Traditional approaches – Agile programming
Design Guidelines
– Motivation
– Common Design Mistakes – Design Rules
1
Design Principles
Motivation: Goals of the Design Phase (1/2)
EVENT SERVER SUPER VISOR CCM Stream ACE RUN-TIME TELECOM SWITCHES Session Router Module Event Filter Module Switch Adapter Module Event Analyzer Module SUPER VISOR SUPER VISOR MIB
Decompose system into
components
– i.e., identify the software
architecture
Determine relationships
between components
– e.g., identify component
dependencies
Determine intercomponent
communication mechanisms
– e.g., globals, function calls,
shared memory, IPC/RPC 2
Design Principles
Motivation: Goals of the Design Phase (2/2)
UPST REAM DOWNST REAM open()=0 close()=0 put()=0 svc()=0 STREAM Head STREAM Tail
Specify component interfaces
– Interfaces should be well-defined
Facilitates component testing
and team communication
Describe component functionality
– e.g., informally or formally
Identify opportunities for systematic
reuse
– Both top-down and bottom-up
Macro Steps in the Design Process
In the design process the orientation moves from
– Customer to developer – What to how
Macro steps include:
1. Preliminary Design
– External design describes the real-world model
– Architectural design decomposes the requirement specification
into software subsystems 2. Detailed Design
– Specify each subsystem
– Further decomposed subsystems, if necessary
4 De sig n Pr in cip le s
Micr
o
Steps
in
the
Design
Pr
ocess
Giv e n a requirements s pec , design is an iter ativ e decision p rocess with the follo wing gener al steps: 1. List the hard decisions and decisions lik ely to change 2. Design a c omponent specification to hide each s uch decision – Mak e decisions that apply to w hole p rog ram fa mily first – Modular iz e most lik ely changes first – Then modular iz e remaining difficult decisions and decisions lik ely to c hange – Design the uses hier arch y a s y ou do this (include reuse decisions) 3. T reat each h igher-le v el component as a specification and apply abo v e process to each 4. Contin ue refining until all design decisions are: – hidden in a c omponent – contain easily comprehensib le components – pro vide individual, independent, lo w -le v el implementation a ssignments 5 Design PrinciplesExample: Designing a Web Server
WWW WWW SERVER SERVER 2: index.html 2: index.html 1: GET ~schmidt 1: GET ~schmidt HTTP/1.0 HTTP/1.0 COMMUNICATION PROTOCOL COMMUNICATION PROTOCOL ((EE..GG.,., HTTP HTTP)) GUI GUI HTML HTML PARSER PARSER REQUESTER REQUESTER GRAPHICS GRAPHICS ADAPTER ADAPTER NETWORK OS KERNEL OS I/O SUBSYSTEM NETWORK ADAPTERS OS KERNEL OS I/O SUBSYSTEM NETWORK ADAPTERS DISPATCHER PROTOCOL HANDLERS WWW CLIENT CLIENT www.cs.wustl.edu/˜jxh/ research/
Web server design
decisions
– Portability issues – I/O demuxing and
concurrency – HTTP protocol processing – File access Web server components – Event dispatcher – Protocol handler – Cached virtual filesystem 6 Design Principles
Key Design Concepts and Principles
Key design concepts and design principles include:
1. Decomposition
2. Abstraction and information hiding
3. Component modularity
4. Extensibility
5. Virtual machine architectures
6. Hierarchical relationships
7. Program families and subsets
Main goal of these
concepts and principles is to:
Manage software
system complexity
Improve software quality
factors
Facilitate systematic
reuse
Resolve common design
challenges
Design Principles
Challenge 1: Determining the Web Server Architecture
Context: A large and complex production web server
Problems:
– Designing the web server as a large monolithic entity is tedious
and error-prone
– Web server developers must work concurrently to improve
productivity
– Portability and resuability are important quality factors
8
Design Principles
Solution: Decomposition
Decomposition handles complexity by splitting large problems into
smaller problems
This “divide and conquer” concept is common to all life-cycle
processes and design techniques
Basic methodology:
1. Select a piece of the problem (initially, the whole problem)
2. Determine the components in this piece using a design paradigm,
e.g., functional, structured, object-oriented, generic, etc.
3. Describe the components interactions
4. Repeat steps 1 through 3 until some termination criteria is met
– e.g., customer is satisfied, run out of time/money, etc. ;-)
9
Design Principles
Decomposition Example: Web Server Framework
Pipes and filters
Component configurator Com p o nent co nfi gu rat o r ~ /home/... Protocol handler Protocol filter Protocol pipeline framework Concurrency strategy framework Tilde expander Cached virtual filesystem I/O strategy framework A dapter
Active object Strategy
S tate A cc ept o r
Asynchronous completion token
M
e
m
ent
o
Reactor/Proactor Strategy Singleton
S tate Event dispatcher Features – High-performance – Flexible concurrency,
demuxing, and caching mechanisms
– Uses frameworks based
on ACE
www.cs.wustl.edu/schmidt/PDF/JAWS.pdf
10
Design Principles
Object-Oriented Decomposition Principles
1. Don’t design components to correspond to execution steps
Since design decisions usually transcend execution time
2. Decompose so as to limit the effect of any one design decision on the rest of the system
Anything that permeates the system will be expensive to change
3. Components should be specified by all information needed to use the component
andnothing more!
Challenge 2: Implementing a Flexible Web Server
Context: The requirements that a production web server must meet
will change over time,e.g.:
– New platforms – New compilers – New functionality – New performance goals
Problems:
– If the web server is “hard coded” using low-level system calls it will
be hard to port
– If web server developers write software that’s tightly coupled with
internal implementation details the software will be hard to evolve
12
Solution: Abstraction
IMPLEMENTATION IMPLEMENTATION ESSENTIAL CHARACTERISTICS UNESSENTIAL DETAILS INTERFACE INTERFACEAbstraction manages complexity
by emphasizingessential
characteristics and suppressing implementation details
Allows postponement of certain
design decisions that occur at
various levels of analysis,e.g.,
– Representational and
algorithmic considerations
– Architectural and structural
considerations
– External environment and
platform considerations 13 De sig n Pr in cip le s
Common
T
ypes
of
Abstraction
1. Procedur al abstr action e. g ., closed s ubroutines 2. Data abstr action e. g ., A DT classes and component models 3. Control abstr action e. g ., loops , iter a tors , fr a me w o rk s , and m u ltitasking ACE Streams ACE ReactorEVENT LOOP EVENT LOOP
APPLI CAT IO N -SPECI FI C EVENT HANDLER FUNCT IONALI TY CALL BACKS LOCAL INVOCAT IONS IP C CLASSES ADT CLASSES ACE T ask EVENT LOOP CALLBACKS CALLBACKS 14 Design Principles
Information Hiding
Information hiding is an important means of achieving abstraction
– i.e., design decisions that are subject to change should be hidden
behind abstract interfaces
Application software should communicate only through well-defined
interfaces
Each interface should be specified by as little information as possible
If internal details change, clients should be minimally affected
– May not even require recompilation and relinking...
Design Principles
Typical Information to be Hidden
Data representations
– i.e., using abstract
data types
Algorithms
– e.g., sorting or
searching techniques
Input and Output
Formats – Machine dependencies,e.g., byte-ordering, character codes Lower-level interfaces
– e.g., ordering of low-level operations, i.e., process sequence
Separating policy and mechanism
– Multiple policies can be implemented
by same mechanisms
e.g., OS scheduling and virtual memory paging
– Same policy can be implemented by
multiple mechanisms
e.g., reliable communication service can be provided by multiple protocols
16
Design Principles
Information Hiding Example: Message Queueing
Message Block Message Queue head_ tail_ SYNCH STRATEGY Message Block next() prev() cont() Message Block next() prev() cont() Message Block next() prev() cont() Data_Block Data_Block Data_Block Data_Block next() prev() cont() AMessage_Queueis a list of ACE_Message_Blocks – Efficiently handles arbitrarily-large message payloads
Design encapsulates and
parameterizes various aspects
– e.g., synchronization, memory
allocators, and reference counting can be added transparently 17 De sig n Pr in cip le s
The
ACE_Message_Block
Class
ACE_Data_Block # base_ : char * # refcnt_ : intACE_Message_Block
+ init (size : size_t) : int + msg_type (type : ACE_Message_Type) + msg_type () : ACE_Message_Type + msg_priority (prio : u_long) + msg_priority () : u_long + clone () : ACE_Message_Block * + duplicate () : ACE_Message_Block * + release () : ACE_Message_Block * + set_flags (flags : u_long) : u_long + clr_flags (flags : u_long) : u_long + copy (buf : const char *,n : size_t) : int + rd_ptr (n : size_t) + rd_ptr () : char * + wr_ptr (n : size_t) + wr_ptr () : char * + length () : size_t + total_length () : size_t + size () : size_t # rd_ptr_ : size_t # wr_ptr_ : size_t # cont_ : ACE_Message_Block * # next_ : ACE_Message_Block * # prev_ : ACE_Message_Block * # data_block_ : ACE_Data_Block *
* 1 Class c h aracteristics Hide messaging implementations from clients ACE_Message _Block cont() data_block() wr_ptr() rd_ptr() PAYLOAD ACE_Data _Block ACE_Message _Block cont() data_block() wr_ptr() rd_ptr() ACE_Data_Block ACE_Message _Block cont() data_block() rd_ptr() wr_ptr() reference_count() = 2 ((11 )) SS IIMM PPLL EE MMEE SSSS AAGG EE SSTT RRUU CCTT UURR EE ((22 )) CC OOMM PPOO SSII TTEE MM EESS SSAA GGEE SS TTRR UUCC TTUU RREE 18 De sig n Pr in cip le s
The
ACE_Message_Queue
Class
+ ACE_Message_Queue (high_water_mark : size_t = DEFAULT_HWM, low_water_mark : size_t = DEFAULT_LWM, notify : ACE_Notification_Strategy * = 0) +
open (high_water_mark : size_t = DEFAULT_HWM,
low_water_mark : size_t = DEFAULT_LWM, notify : ACE_Notification_Strategy * = 0) : int +
flush () : int
+
notification_strategy (s : ACE_Notification_Strategy *) : void
+
is_empty () : int
+
is_full () : int
+
enqueue_tail (item : ACE_Message_Block *,
timeout : ACE_Time_Value * = 0) : int +
enqueue_head (item : ACE_Message_Block *,
timeout : ACE_Time_Value * = 0) : int +
enqueue_prio (item : ACE_Message_Block *,
timeout : ACE_Time_Value * = 0) : int +
dequeue_head (item : ACE_Message_Block *&,
timeout : ACE_Time_Value * = 0) : int +
dequeue_tail (item : ACE_Message_Block *&,
timeout : ACE_Time_Value * = 0) : int +
high_water_mark (new_hwm : size_t) : void
+
high_water_mark (void) : size_t
+
low_water_mark (new_lwm : size_t) : void
+
low_water_mark (void) : size_t
+ close () : int + deactivate () : int + activate () : int + pulse () : int + state () : int
# head_ : ACE_Message_Block * # tail_ : ACE_Message_Block * # high_water_mark_ : size_t # low_water_mark_ : size_t
ACE_Message_Queue SYNCH_STRATEGY Class c h aracteristics Note ho w the synchronization aspect c an be str a tegiz ed! 19
Challenge 3: Determining the Units of Web Server
Decomposition
Context: A production web server that uses abstraction and
information hiding
Problems:
– Need to determine the appropriate units of decomposition, which
should
Possess well-specifiedabstract interfaces and
Have highcohesion and low coupling
20
Solution: Component Modularity
NAMING TRADING LOCKING EVENT LOOP APPLICATION -SPECIFIC GLUE CODE LOGGING TIME
Amodular system is one that’s structured into identifiable abstractions called
components
– A software entity that represents an
abstraction
– A “work” assignment for developers – A unit of code that
has one or more names
has identifiable boundaries
can be (re-)used by other components
encapsulates data
hides unnecessary details
can be separately compiled
21
Design Principles
Designing Component Interfaces
A component interface consists of
several types of ports:
– Exports
Services provided to other
components,e.g., facets and
event sources
– Imports
Services requested from
other components,e.g.,
receptacles and event sinks
– Access Control
Not all clients are equal,e.g.,
protected/private/public CALL BACKS CONTAINER COMPONENT EXECUTOR HOME FACETS RECEPTACLES
EVENT SINK EVENT SOURCE
Define components that
provide multiple interfaces and implementations
Anticipate change
22
Design Principles
Component Modularity Example: Stream Processing
NETWORK INTERFACE OR PSEUDO-DEVICES STREAM Tail Multiplexor APPLICATION Stream STREAM Head APPLICATION Stream UPSTREAM DOW N STREAM MESSAGE WRITE
TASK READTASK
MODULE
open()=0 close()=0 put()=0 svc()=0
A Stream allows flexible
configuration of layered processing modules
AStreamcomponent contains
a stack ofModulecomponents
EachModulecontains two
Taskcomponents
– i.e., read and writeTasks
EachTaskcontains a
Message Queuecomponent
and aThread Manager
component
Design Principles
Benefits of Component Modularity
Modularity facilitates software
quality factors,e.g.,:
Extensibility!well-defined, abstract interfaces Reusability!low-coupling, high-cohesion Compatibility!design “bridging” interfaces
Portability!hide machine
dependencies
Modularity is important for good designs since it:
Enhances forseparation of
concerns
Enables developers to
reduce overall system
complexity viadecentralized
software architectures
Increasesscalability by
supporting independent and concurrent development by multiple personnel
24
Design Principles
Criteria for Evaluating Modular Designs
Component decomposabilityAre larger components
decomposed into smaller components?
Component composability
Are larger components
composed from existing smaller components?
Component understandability
Are components separately
understandable?
Component continuity
Do small changes to the
specification affect a
localized and limited number of components?
Component protection
Are the effects of run-time
abnormalities confined to a small number of related components?
25
Design Principles
Principles for Ensuring Modular Designs
Language support for componentsComponents should correspond to
syntactic units in the language
Few interfaces
Every component should
communicate with as few others as possible
Small interfaces (weak coupling)
If any two components communicate
at all, they should exchange as little information as possible
Explicit Interfaces
Whenever two
components A and B communicate, this must be obvious from the text of A or B or both
Information Hiding
All information about a
component should be private unless it’s specifically declared public
26
Design Principles
Challenge 4: “Future Proofing” the Web Server
Context: A production web server whose requirements will change
over time
Problems:
– Certain design aspects seem constant until they are examined in
the overall structure of an application
– Developers must be able to easily refactor the web server to
account for new sources of variation
Solution: Extensibility
Extensible software is important to support successions of quick
updates and additions to address new requirements and take advantage of emerging opportunities/markets
Extensible components must beboth open and closed, i.e., the
“open/closed” principle:
– Open component!still available for extension
This is necessary since the requirements and specifications are
rarely completely understood from the system’s inception
– Closed component!available for use by other components
This is necessary since code sharing becomes unmanageable
when reopening a component triggers many changes
28
Extensibility Example: Active Object Tasks
Event Handler handle_input() handle_output() handle_exception() handle_signal() handle_timeout () handle_close() get_handle()=0 Shared Object init()=0 fini ()=0 info()=0 Svc Handler Service Object A APPLICATION -SPECIFIC APPLICATION -INDEPENDENT Message Queue SYNCH_STRATEGY PEER_STREAM suspend()=0 resume()=0 SYNCH STRATEGY A A Task open()=0 close()=0 put()=0 svc()=0 SYNCH STRATEGY A Features
– Taskscan register with a
Reactor
– They can be dynamically
linked
– They can queue data – They can run as “active
objects”
JAWS uses inheritance and
dynamic binding to produce task components that are
both open and closed
29
Design Principles
Challenge 5: Separating Concerns for Layered
Systems
Context: A production web server whose requirements will change
over time
Problems:
– To enhance reuse and flexibility, it is often necessary to
decompose a web server into smaller, more manageable units
that arelayered in order to
Enhance reuse,e.g., multiple higher-layer services can share
lower-layer services
Transparently and incrementally enhancement functionality
Improve performance by allowing the selective omission of
unnecessary service functionality
Improve implementations, testing, and maintenance
30 De sig n Pr in cip le s
Solution:
Vir
tual
M
ac
hine
Ar
c
hitectures
A vir tual machine p ro vides an e x tended “softw are instr uction set” – Extensions pro vide additional data types and associated “softw are instr uctions” – Modeled after hardw are instr uction set pr imitiv es that w o rk on a limited set o f data types A vir tual machine la y er pro vides a s et of oper ations that are u seful in d e v eloping a fa mily of similar systemsAPPLICATION PRESENTATION SESSION TRANSPORT NETWORK DATA LINK PHYSICAL
APPLICATION PRESENTATION SESSION TRANSPORT NETWORK DATA LINK PHYSICAL
APPLICATION PRESENTATION SESSION TRANSPORT NETWORK DATA LINK PHYSICAL
APPLICATION PRESENTATION SESSION TRANSPORT NETWORK DATA LINK PHYSICAL
NETWORK DATA LINK PHYSICAL NETWORK DATA LINK PHYSICAL NETWORK DATA LINK PHYSICAL NETWORK DATA LINK PHYSICAL
HH OST OST AA HH OST OST BB GG ATEWAY ATEWAY AA GG ATEWAY ATEWAY BB
VIRTUAL LINK PHYSICAL LINK
Design Principles
Virtual Machine Layers for the ACE Toolkit
PROCESSES/ THREADS DYNAMIC LINKING SHARED MEMORY SELECT/ IO COMP FILE SYS APIS WIN32 NAMED
PIPES & UNIX
STREAM PIPES
UNIX FIFOS
C
APIS SOCKETSTLI /
COMMUNICATION SUBSYSTEM
VIRTUAL MEMORY & FILE SUBSYSTEM
GENERAL OPERATING SYSTEM SERVICES
PROCESS/THREAD SUBSYSTEM FRAMEWORK LAYER ACCEPTOR CONNECTOR NETWORKED SERVICE COMPONENTS LAYER NAME SERVER TOKEN SERVER LOGGING SERVER GATEWAY SERVER SOCK SAP/ TLI SAP FIFO SAP LOG MSG SERVICE HANDLER TIME SERVER C++ WRAPPER FACADE LAYER SPIPE SAP CORBA HANDLER FILE SAP SHARED MALLOC
THE ACE ORB
(TAO)
JAWS ADAPTIVE
WEB SERVER STANDARDS-BASED MIDDLEWARE
REACTOR/ PROACTOR PROCESS/ THREAD MANAGERS STREAMS SERVICE CONFIG -URATOR SYNCH WRAPPERS MEM MAP OS ADAPTATION LAYER www.cs.wustl.edu/schmidt/ACE.html 32 De sig n Pr in cip le s
Other
Examples
o
f
V
ir
tual
Mac
hines
Computer architectures e. g ., c ompiler ! assemb ler ! obj code ! microcode ! gates , tr ansistors , signals , etc. Oper ating systems e. g .,L in u x Har d ware Mac hine Software Vir tual Mac hine instr uction set set of system calls restar tab le instr uctions restar tab le system calls interr upts/tr aps signals interr upt/tr ap handlers signal handlers b loc king interr upts masking signals interr upt stac k signal stac k J a v a Vir tual Machine (JVM) Abstr a cts a w a y from details of the under lying O S 33 Design PrinciplesChallenge 6: Separating Concerns for Hierarchical
Systems
Context: A production web server whose requirements will change
over time
Problems:
– Developers need to program components at different levels of
abstraction independently
– Changes to one set of components should be isolated as much
as possible from other components
– Need to be able to “visualize” the structure of the web server
design
34
Design Principles
Solution: Hierarchical Relationships
Hierarchies reduce component interactions by restricting the
topology of relationships
A relation defines a hierarchy if it partitions units into levels (note
connection tovirtual machine architectures)
– Level 0 is the set of all units that use no other units
– Leveliis the set of all units that use at least one unit at level<i
and no unit at leveli.
Hierarchies form the basis ofarchitectures and designs
– Facilitates independent development – Isolates ramifications of change – Allows rapid prototyping
Design Principles
Hierarchy Example: JAWS Architecture
svc_run
REQUEST PROCESSING LAYER
Options
s
HTTP
Handler Handler HTTP Handler HTTP
HTTP Acceptor Reactor HTTP Processor Msg Queue s svc_run svc_run svc_run QUEUEING LAYER I/O DEMUXING LAYER 36 Design Principles
Defining Hierarchies
Relations that define hierarchies include:
– Uses
– Is-Composed-Of
– Is-A
– Has-A
The first two are general to all design methods, the latter two are more particular to OO design and programming ACE_IPC_SAP ACE_Addr ACE_SOCK_IO ACE_SOCK ACE_SOCK_Acceptor ACE_INET_Addr ACE_SOCK_Stream ACE_SOCK_Connector 37 sig n Pr in cip le s
The
Uses
Relation
(1/3)
C lass X C lass Y X Uses Y if the c orrect functioning of X depends on the a v a ilability o f a correct implementation o f Y Note , uses is not necessar ily the s ame a s in v o k e s : – Some in v o cations are not uses e. g ., e rror logging – Some uses don’t in v olv e in v o cations e. g ., m essage passing, interr upts , shared memor y access A uses relation does not necessar ily yield a hier arch y (a v oid cycles ...) Design PrinciplesThe Uses Relation (2/3)
AllowX to use Y when:
– X is simpler because it uses Y
e.g., Standard C++ library classes
– Y is not substantially more complex because
it is not allowed to useX
– There is a useful subset containingY and not
X
i.e., allows sharing and reuse of Y
– There is no conceivably useful subset containingX but not Y
i.e., Y is necessary for X to function
correctly
Uses relationships can exist between classes, frameworks, subsystems, etc.
Acceptor-Connector Reactor Proactor
Service
Configurator Streams Task
De sig n Pr in cip le s
The
Uses
Relation
(3/3)
A h ier a rch y in the uses relation is essential for designing reusab le softw are systems Ho w e v e r, cer tain s oftw are systems require controlled violation of a uses hier arch y – e. g ., a synchronous comm unication protocols , OO callbac ks in fr ame w or ks , signal handling, etc. – Upcalls are one w a y to c ontrol these non-hier archical dependencies Rule of thumb : – Star t w ith a n in v ocation h ier a rch y and eliminate those in v ocations (i.e ., “calls”) that are not uses relationships 40 Design PrinciplesThe Is-Composed-Of Relation
Theis-composed-of relationship shows how the
system is broken down in components
Xis-composed-offx
i
gif X is a group of
componentsx
ithat share some common
purpose
The following diagram illustrates some of the is-composed-of relationships in JAWS
HTTP Handler Sock Stream HTTP Handler Sock Stream HTTP Handler Sock Stream HTTP Acceptor Sock Acceptor Reactor 41 De sig n Pr in cip le s
The
Is-Composed-Of
R
elation
Man y prog ra mming languages suppor t the is-composed-of relation via some higher-le v el component or record str u ctur ing technique Ho w e v e r, the follo wing are not equiv a lent: – le v e l (vir tual machine) – component (an entity that hides one or more “secrets”) – a s ubprog ra m (a c ode unit) Components and le v e ls need not be identical, as a c omponent ma y appear in se v e ra l le v els o f a uses hier arch y 42 Design PrinciplesThe Is-A Relation
This “ancestor/descendant” relationship is associated with object-oriented design and programming languages that possess inheritance and dynamic binding
class X possessesIs-A relationship with class Y if instances of class X are specialization of class Y.
– e.g., anHTTP_1_0_HandlerIs-A
ACE_Event_Handlerthat is specialized for
processing HTTP 1.0 requests
ACE_Event_Handler
handle_input()
get_handle()
HTTP_1_0
Handler
HTTP_1_1
Handler
43De sig n Pr in cip le s
The
Has-A
R
elation
This “client” relationship is a ssociated w ith object-or iented design and prog ra mming languages that possess classes and objects class X possesses a Has-A relationship w ith class Y if instances of class X c ontain a n instance(s) of class Y . – e. g ., the J A WS w e b s er v e r Has-A Reactor , HTTP_Acceptor , and CV_FilesytemJA
WS
We
b
Serv
er
HTTP
A
ccept
or
R eact or C V _Filesy st em 44Challenge 7: Enabling Expansion and Contraction of
Software
Context: A production web server whose requirements will change
over time
Problems:
– It may be necessary to reduce the overall functionality of the
server to run in resource-constrained environments
– To meet externally imposed schedules, it may be necessary to
release the server without all the features enabled
45
Design Principles
Solution: Program Families and Subsets
This principle should be applied to facilitateextension and
contraction of large-scale software systems, particularly reusable
middleware infrastructure
– e.g., JAWS, ACE, etc.
Program families are natural way to detect and implementsubsets
– Minimize footprints for embedded systems – Promotes system reusability
– Anticipates potential changes
Heuristics for identifying subsets:
– Analyze requirements to identify minimally useful subsets – Also identify minimal increments to subsets
46 De sig n Pr in cip le s
Example
of
Pr
ogram
F
amilies:
J
A
WS
and
T
A
O
(1) THE A CE ORB (T A O ) NETW ORKREAL-TIME ORB CORE
A
CE components
IOP
IOP
PLUGGABLEORB & XPOR
T
PR
O
T
OCOLS
PLUGGABLEORB & XPOR
T
PR
O
TOCOLS
REAL-TIME I/OSUBSYSTEM HIGH-SPEED
NETW ORK INTERF A C E OS KERNEL
REAL-TIME I/OSUBSYSTEM HIGH-SPEED
NETW ORK INTERF A C E OS KERNEL ORB R UN-TIME SCHEDULER IDL SKELET ON IDLSTUBS oper ation ()
out args + retur
n v alue OBJECT(SER V ANT) in args REAL-TIMEOBJECT AD APTER CLIENT OBJREF (2) The J A WS W eb Ser v er F rame w o rk Service Configurator Strategy Strategy Singleton State State Acceptor
Pipes and Filter
s Active Object Adapter Ser vice Configurator Event Dispatc her Concurrenc y StrategyFrame w ork Pr otocol
Handler Protocol Filter Tilde Expander /home/... ~ Reactor/Pr oactor Memento I/O StrategyFrame
w ork Cac hed Vir tual Filesystem Pr otocol Pipeline Frame w ork Async hr onous Completon Token T A O is a high-perf o rm ance , real-time implementation o f the CORBA s pecification J A WS is a h igh-perf o rm ance , adaptiv e W eb ser v er that implements the HTTP specification J A WS and T A O w ere d e v eloped using the wr apper fa cades and fr ame w or ks pro vided b y the A CE toolkit 47
De sig n Pr in cip le s
Other
Examples
o
f
P
rogram
F
amilies
and
S
ubsets
Diff erent ser vices for diff erent mar k ets – e. g ., d iff e rent alphabets , diff erent v e rt ical applications , d iff e rent I/O fo rm ats Diff erent hardw are o r s oftw are p latf or ms – e. g ., c ompilers or OSs Diff erent resource tr ade-offs – e. g ., s peed vs space Diff erent inter nal resources – e. g ., s hared data s tr uctures and libr a ry routines Diff erent e x ter nal e v ents – e. g ., UNIX I/O de vice interf ace Bac k w a rd compatibility – e. g ., s ometimes it is impor tant to retain b ugs! 48 Design PrinciplesConventional Development Processes
Waterfall Model
– Specify, analyze, implement, test (in sequence) – Assumes that requirements can be specified up front
Spiral Model
– Supports iterative development – Attempts to assess risks of changes
Rapid Application Development
– Build a prototype – Ship it :-)
49
Design Principles
Agile Processes
Stresses customer satisfaction, and therefore, involvement
– Provide what the customer wants, as quickly as possible
– Provideonly what the customer wants
Encourages changes in requirements
Relies on testing
For example,eXtreme Programmingpractices
– Planning, designing, coding, testing
50
Design Principles
eXtreme Programming: Planning
Technology
Spike
System
Prototype
User
Story
Planning
Game
Iteration
Commitment ScheduleChange in Requirements, Risk, or Developement Environment
Risk Estimates
Time
Requirements
based on http://www.extremeprogramming.org/rules/planninggame.html
Start withuser stories
– Written by customers, to
specify system requirements
– Minimal detail, typically
just a few sentences on a card
– Expected development
time: 1 to 3 weeks each, roughly
Planning game creates
commitment schedule for entire project
Each iteration should take
2-3 weeks
eXtreme Programming: Designing
Defer design decisions as long as possible
Advantages:
– Simplifies current task (just build what is needed) – You don’t need to maintain what you haven’t built
– Time is on your side: you’re likely to learn something useful by the
time you need to decide
– Tomorrow may never come: if a feature isn’t needed now, it might
never be needed
Disadvantages:
– Future design decisions may require rework of existing
implementation
– Ramp-up time will probably be longer later
Therefore, always try to keep designs as simple as possible
52
eXtreme Programming: Coding
Pair programming
– Always code with a partner
– Always test as you code
Pair programming pays off by supporting good implementation,
reducing mistakes, and exposing more than one programmer to the design/implementation
If any deficiencies in existing implementation are noticed, either fix
them or note that they need to be fixed
53
Design Principles
eXtreme Programming: Testing
Unit tests are writtenbefore code
Code must pass both its unit test and all regression tests before
committing
In effect, the test suite defines the system requirements
– Significant difference from other development approaches – If a bug is found, a test for it must be added
– If a feature isn’t tested, it can be removed
54
Design Principles
Agile Processes: Information Sources
Kent Beck,Extreme Programming Explained: Embrace Change,
Addison-Wesley, ISBN 0201616416, 1999
Kent Beck, “Extreme Programming”,C++ Report 11:5, May 1999,
pp. 26–29+
John Vlissides, “XP”, interview with Kent Beck in the Pattern
Hatching Column,C++ Report 11:6, June 1999, pp. 44-52+
Kent Beck, “Embracing Change with Extreme Programming”,IEEE
Computer 32:10, October 1999, pp. 70-77
http://www.extremeprogramming.org/ http://www.xprogramming.com/
http://c2.com/cgi/wiki?ExtremeProgrammingRoadmap
Design Principles
Design Guidelines: Motivation
Design is the process of organizing structured solutions to tasks
from a problem domain
This process is carried out in many disciplines, in many ways
– There are many similarities and commonalities among design
processes
– There are also many common design mistakes . . .
The following pages provide a number of “design rules.”
– Remember, these rules are simply suggestions on how to better
organize your design process,not a recipe for success!
56
Design Principles
Common Design Mistakes (1/2)
Depth-first design
– only partially satisfy the requirements – experience is best cure for this problem . . .
Directly refining requirements specification
– leads to overly constrained, inefficient designs
Failure to consider potential changes
– always design for extension and contraction
Making the design too detailed
– this overconstrains the implementation
57
Design Principles
Common Design Mistakes (2/2)
Ambiguously stated design
– misinterpreted at implementation
Undocumented design decisions
– designers become essential to implementation
Inconsistent design
– results in a non-integratable system, because separately
developed modules don’t fit together
58
Design Principles
Rules of Design (1/8)
Make sure that the problem is well-defined
– All design criteria, requirements, and constraints, should be
enumerated before a design is started
– This may require a “spiral model” approach
What comes before how
– i.e., define the service to be performed at every level of
abstraction before deciding which structures should be used to realize the services
Separate orthogonal concerns
– Do not connect what is independent – Important at many levels and phases . . .
Rules of Design (2/8)
Design external functionality before internal functionality.
– First consider the solution as a black-box and decide how it
should interact with its environment
– Then decide how the black-box can be internally organized. Likely
it consists of smaller black-boxes that can be refined in a similar fashion
Keep it simple.
– Fancy designs are buggier than simple ones; they are harder to
implement, harder to verify, and often less efficient
– Problems that appear complex are often just simple problems
huddled together
– Our job as designers is to identify the simpler problems, separate
them, and then solve them individually
60
Rules of Design (3/8)
Work at multiple levels of abstraction
– Good designers must be able to move between various levels of
abstraction quickly and easily Design for extensibility
– A good design is “open-ended,”i.e., easily extendible
– A good design solves a class of problems rather than a single
instance
– Do not introduce what is immaterial – Do not restrict what is irrelevant
Use rapid prototyping when applicable
– Before implementing a design, build a high-level prototype and
verify that the design criteria are met
61
Design Principles
Rules of Design (4/8)
Details should depend upon abstractions
– Abstractions should not depend upon details – Principle of Dependency Inversion
The granule of reuse is the same as the granule of release
– Only components that are released through a tracking system can
be effectively reused
Classes within a released component should share common closure
– That is, if one needs to be changed, they all are likely to need to
be changed
– i.e., what affects one, affects all
62
Design Principles
Rules of Design (5/8)
Classes within a released component should be reused together
– That is, it is impossible to separate the components from each
other in order to reuse less than the total
The dependency structure for released components must be a DAG
– There can be no cycles
Dependencies between released components must run in the
direction of stability
– The dependee must be more stable than the depender
The more stable a released component is, the more it must consist
of abstract classes
– A completely stable component should consist of nothing but
abstract classes 63
Design Principles
Rules of Design (6/8)
Where possible, use proven patterns to solve design problems
When crossing between two different paradigms, build an interface
layer that separates the two
– Don’t pollute one side with the paradigm of the other
64
Design Principles
Rules of Design (7/8)
Software entities (classes, modules, etc) should be open for
extension, but closed for modification
– The Open/Closed principle – Bertrand Meyer
Derived classes must usable through the base class interface
without the need for the user to know the difference
– The Liskov Substitution Principle
65
Design Principles
Rules of Design (8/8)
Make it work correctly, then make it work fast
– Implement the design, measure its performance, and if
necessary, optimize it
Maintain consistency between representations
– e.g., check that the final optimized implementation is equivalent to
the high-level design that was verified
– Also important for documentation . . .
Don’t skip the preceding rules!
– Clearly, this is the most frequently violated rule!!! ;-)
66
Design Principles
Concluding Remarks
Good designs can generally be distilled into a few key principles:
– Separate interface from implementation
– Determine what iscommon and what is variable with an interface
and an implementation
– Allow substitution ofvariable implementations via a common
interface
i.e., the “open/closed” principle
– Dividingcommonality from variability should be goal-oriented
rather than exhaustive
Design is not simply the act of drawing a picture using a CASE tool
or using graphical UML notation!!!
– Design is a fundamentallycreative activity