Design and Software Architecture
Design and Software Architecture
Architecture
Ch. 4
Outline
What is design
How can a system be decomposed into modules
What is a modules interface
What are the main relationships among modules
Prominent software design techniques and
information hiding
The UML collection of design notations
Design of concurrent and distributed software
Design patterns
Architectural styles
Component based software engineering
Ch. 4
What is design?
Provides structure to any artifact
Decomposes system into parts,
assigns responsibilities, ensures
that parts fit together to achieve a
global goal
Design refers to both an activity
and the result of the activity
Ch. 4
Software architecture
Shows gross structure and organization of
the system to be defined
Its description includes description of
Ch. 4
Example
Ch. 4
10
Product families
Different versions of the same system
e.g. a family of mobile phones
members of the family may differ in network
standards, end-user interaction languages,
Ch. 4
11
Ch. 4
12
Sequential completion:
the wrong way
Design first member of product
family
Modify existing software to get
next member products
Ch. 4
13
Sequential completion:
a graphical view
Requirements
Requirements
Requirements
1
2
2
Version 1
3
final
product
Version 1
4
44
Version 1
Version 2
intermediate
design
Version 2 5
3
6
7
Ch. 4
Version 3
14
How to do better
Anticipate definition of all family
members
Identify what is common to all
family members, delay decisions
that differentiate among different
members
We will learn how to manage
change in design
Ch. 4
15
Module
A well-defined component of a
software system
A part of a system that provides a
set of services to other modules
Services are computational elements
that other modules may use
Ch. 4
16
Questions
How to define the structure of a
modular system?
What are the desirable properties
of that structure?
Ch. 4
17
18
Relations
Transitive closure r+ of r
Mi r+ Mj iff
Mi r Mj or Mk in S s.t. Mi r Mk and Mk r+ Mj
(We assume our relations to be irreflexive)
r is a hierarchy iff there are no two
elements Mi, Mj s.t. Mi r+ Mj Mj r+ Mi
Ch. 4
19
Relations
Relations can be represented as
graphs
A hierarchy is a DAG (directed
M1
M1
acyclic graph)
a graph
M3
M2
M1,2
M1,1
a DAG
M1,2,1
M4
M6
a)
M1,3
M1,2,1,1
M1,2,2
M2
M3
M4
Ch. 4
b)
20
A is a client of B; B is a server
Ch. 4
21
Desirable property
USES should be a hierarchy
Hierarchy makes software easier to
understand
we can proceed from leaf nodes (who
do not use others) upwards
22
Hierarchy
Organizes the modular structure
through levels of abstraction
Each level defines an abstract
(virtual) machine for the next level
level can be defined precisely
Mi has level 0 if no Mj exists s.t. Mi r Mj
let k be the maximum level of all nodes
Mj s.t. Mi r Mj. Then Mi has level k+1
Ch. 4
23
IS_COMPONENT_OF
Used to describe a higher level module as
constituted by a number of lower level
modules
A IS_COMPONENT_OF B
B consists of several modules, of which one is A
B COMPRISES A
MS,i={Mk|MkSMk IS_COMPONENT_OF Mi}
we say that MS,i IMPLEMENTS Mi
Ch. 4
24
A graphical view
M M M
8 9
7
M
5
M2
M3
M
6
M4
M1
(IS_COMPONENT_OF)
M1
M2
M3
M M M
8 9
7
M
5
M4
M
6
(COMPRISES)
25
Product families
Careful recording of (hierarchical)
USES relation and
IS_COMPONENT_OF supports
design of program families
Ch. 4
26
27
28
Ch. 4
29
Information hiding
Basis for design (i.e. module decomposition)
Implementation secrets are hidden to clients
They can be changed freely if the change
does not affect the interface
Golden design principle
INFORMATION HIDING
Try to encapsulate changeable design decisions as
implementation secrets within module implementations
Ch. 4
30
31
Interface design
Interface should not reveal what
we expect may change later
It should not reveal unnecessary
details
Interface acts as a firewall
preventing access to hidden parts
Ch. 4
32
Prototyping
Once an interface is defined,
implementation can be done
first quickly but inefficiently
then progressively turned into the
final version
33
policy
how do we select the next task to resume?
different scheduling policies are available
they may be hidden to clients
they can be encapsulated as module secrets
Ch. 4
34
Design notations
Notations allow designs to be
described precisely
They can be textual or graphic
We illustrate two sample notations
TDN (Textual Design Notation)
GDN (Graphical Design Notation)
35
36
An example
module X
uses Y, Z
exports var A : integer;
type B : array (1. .10) of real;
procedure C ( D: in out B; E: in integer; F: in real);
Here is an optional natural-language description of what
A, B, and C actually are, along with possible constraints
or properties that clients need to know; for example, we
might specify that objects of type B sent to procedure C
should be initialized by the client and should never
contain all zeroes.
implementation
If needed, here are general comments about the rationale
of the modularization, hints on the implementation, etc.
is composed of R, T
end X
Ch. 4
37
Comments in TDN
May be used to specify the protocol
to be followed by the clients so that
exported services are correctly
provided
e.g., a certain operation which does the
initialization of the module should be
called before any other operation
e.g., an insert operation cannot be
called if the table is full
Ch. 4
38
Example (cont.)
module R
uses Y
exports var K : record . . . end;
type B : array (1. .10) of real;
procedure C (D: in out B; E: in integer; F: in real);
implementation
end R
.
.
.
module T
uses Y, Z, R
exports var A : integer;
implementation
end T
.
.
.
Ch. 4
39
Benefits
Notation helps describe a design
precisely
Design can be assessed for
consistency
having defined module X, modules R and
T must be defined eventually
if not incompleteness
R, T replace X
either one or both must use Y, Z
Ch. 4
40
Example: a compiler
module COMPILER
exports procedure MINI (PROG: in file of char;
CODE: out file of char);
MINI is called to compile the program stored in PRO
and produce the object code in file CODE
implementation
A conventional compiler implementation.
ANALYZER performs both lexical and syntactic analy
and produces an abstract tree, as well as entries in
symbol table; CODE_GENERATOR generates code
starting from the abstract tree and information stor
in the symbol table. MAIN acts as a job coordinator.
is composed of ANALYZER, SYMBOL_TABLE,
ABSTRACT_TREE_HANDLER, CODE_GENERATOR, MA
end COMPILER
Ch. 4
41
Other modules
module MAIN
uses ANALYZER, CODE_GENERATOR
exports procedure MINI (PROG: in file of char;
CODE: out file of char);
end MAIN
module ANALYZER
uses SYMBOL_TABLE, ABSTRACT_TREE_HANDLER
exports procedure ANALYZE (SOURCE: in file of char);
SOURCE is analyzed; an abstract tree is produced
by using the services provided by the tree handler,
and recognized entities, with their attributes, are
stored in the symbol table.
...
end ANALYZER
Ch. 4
42
Other modules
module CODE_GENERATOR
uses SYMBOL_TABLE, ABSTRACT_TREE_HANDLER
exports procedure CODE (OBJECT: out file of char);
The abstract tree is traversed by using the
operations exported by the
ABSTRACT_TREE_HANDLER and accessing
the information stored in the symbol table
in order to generate code in the output file.
end CODE_GENERATOR
Ch. 4
43
Module
R
Module
T
C
Module Z
Ch. 4
44
X's decomposition
Module Y
Module X
K
Module
R
Module
T
Module Z
Ch. 4
45
Categories of modules
Functional modules
traditional form of modularization
provide a procedural abstraction
encapsulate an algorithm
e.g. sorting module, fast Fourier
transform module,
Ch. 4
46
Ch. 4
47
48
49
Example (cont.)
Interface of the abstract object STACK
exports
procedure PUSH (VAL: in integer);
procedure POP_2 (VAL1, VAL2: out integer);
Ch. 4
50
Design assessment
How does the design anticipate
change in type of expressions to
be evaluated?
e.g., it does not adapt to unary
operators
Ch. 4
51
module STACK_HANDLER
exports
type STACK = ?;
This is an abstract data-type module; the data structure
is a secret hidden in the implementation part.
procedure PUSH (S: in out STACK ; VAL: in integer);
procedure POP (S: in out STACK ; VAL: out integer);
function EMPTY (S: in STACK) : BOOLEAN;
.
.
.
end STACK_HANDLER
Ch. 4
52
ADTs
Correspond to Java and C++ classes
Concept may also be implemented by Ada
private types and Modula-2 opaque types
May add notational details to specify if
certain built-in operations are available by
default on instance objects of the ADT
e.g., type A_TYPE: ? (:=, =) indicates that
assignment and equality check are available
Ch. 4
53
An example:
simulation of a gas station
module FIFO_CARS
uses CARS
exports
type QUEUE : ?;
procedure ENQUEUE (Q: in out QUEUE ; C: in CARS);
procedure DEQUEUE (Q: in out QUEUE ; C: out CARS);
function IS_EMPTY (Q: in QUEUE) : BOOLEAN;
function LENGTH (Q: in QUEUE) : NATURAL;
procedure MERGE (Q1, Q2 : in QUEUE ; Q : out QUEUE);
This is an abstract data-type module representing
queues of cars, handled in a strict FIFO way;
queues are not assignable or checkable for equality,
since := and = are not exported.
end FIFO_CARS
Ch. 4
54
end GENERIC_STACK_2
Ch. 4
55
Instantiation
Possible syntax:
module INTEGER_STACK_2 is
GENERIC_STACK_2 (INTEGER)
Ch. 4
56
More on genericity
How to specify that besides a type also an
operation must be provided as a
parameter
generic module M (T) with OP(T)
uses ...
...
end M
Instantiation
module M_A_TYPE is M(A_TYPE)
PROC(M_A_TYPE)
Ch. 4
57
Ch. 4
58
Software generation
e.g., compiler compilers (yacc,
interface prototyping tools)
Ch. 4
59
Stepwise refinement
A systematic, iterative program design
technique that unfortunately may lead
to software that is hard to evolve
At each step, problem P decomposed
into
sequence of subproblems: P1; P2; Pn
a selection: if (cond) then P1 else P2
an iteration: while (cond) do_something
Ch. 4
60
Example
derivation of selection sort
Step 1
let n be the length of the array a to be sorted;
i := 1 ;
while i < n loop
find the smallest of ai .. .an, and exchange
it with the element at position i;
i := i + 1;
end loop;
Ch. 4
61
Step 2
let n be the length of the array a to be
sorted;
i := 1 ;
while i < n loop
j := n;
while j > i loop
if a(i) > a(j) then
interchange the
elements at
positions j and i ;
end if;
j := j - 1;
end loop;
i := i + 1;
end loop;
Ch. 4
62
Step 3
let n be the length of the array a to be
sorted;
i := 1 ;
while i < n loop
j := n;
while j > i loop
if a(i) > a(j) then
x := a(i);
a(i) := a(j);
a(j) := x;
end if;
j := j - 1;
end loop;
i := i + 1;
end loop;
Ch. 4
63
Decomposition tree
Stepwise refinement process may be
depicted by a decomposition tree
(DT)
root labeled by name of top problem
subproblem nodes labeled as children of
parent node corresponding to problem
children from left to right represent
sequential order of execution
if and while nodes denoted by suitable
decoration
Ch. 4
64
Example
Step 1
P;
P problem to solve
Step 2
P1; P2; P3;
P decomposed into sequence
Step 3
P1;
while C loop
P2,1; P2 decomposed into a loop
end loop;
P3;
Step 4
P1;
while C loop
if C1 then P2,1 decomposed into selection
P2,1,1;
else
P2,1,2;
end if;
end loop;
Ch. 4
P3;
65
Corresponding DT
P
P
C
P
C
P
2,1, 1
2,1
not C
1
P
2,1, 2
Ch. 4
66
Relation with
IS_COMPOSED_OF
Let M, M1, M2, M3 be modules
representing P, P1, P2, P3
We cannot write
M IS_COMPOSED_OF {M1,M2,M3}
67
An assessment of stepwise
refinement (1)
Stepwise refinement is a
programming technique, not a
modularization technique
When used to decompose system
into modules, it tends to analyze
problems in isolation, not
recognizing commonalities
It does not stress information hiding
Ch. 4
68
An assessment of stepwise
refinement (2)
No attention is paid to data (it
decomposes functionalities)
Assumes that a top function exists
but which one is it in the case of an
operating system? or a word processor?
69
Example
a program analyzer
Step 1
Recognize a program stored in a given file f;
Step 2
correct := true;
analyze f according to the language
definition;
if correct then
print message "program correct";
else
print message "program incorrect";
end if;
Ch. 4
70
Step 3
correct := true;
perform lexical analysis:
store program as token sequence in file ft
and symbol table in file fs, and set error_in_lexical_pha
accordingly;
if error_in_lexical_phase then
correct := false;
else
perform syntactic analysis and set Boolean variable
error_in_syntactic_phase accordingly:
if error_in_syntactic_phase then
correct := false;
end if;
end if;
if correct then
print message "program correct";
else
print message "program incorrect";
end if;
Ch. 4
71
Commitments
Two passes
Lexical analysis comes first on the
entire program, producing two files
72
Module SCANNER
hides details of lexical structure of the language
exports operation to provide next token
Module PARSER
hides data structure used to perform syntactic
analysis (abstract object PARSER)
Ch. 4
73
Ch. 4
74
Handling anomalies
Defensive design
A module is anomalous if it fails to
provide the service as expected
and as specified in its interface
An exception MUST be raised when
anomalous state is recognized
Ch. 4
75
76
77
Example
module M
exports . . .
procedure P (X: INTEGER; . . .)
raises X_NON_NEGATIVE_EXPECTED,
INTEGER_OVERFLOW;
X is to b e positive; if not, exception
X_NON_NEGATIVE_EXPECTED is raised;
INTEGER_OVERFLOW is raised if internal
computation of P generates an overflow
end M
.
.
.
Ch. 4
78
Example of exception
propagation
module L
uses M imports P (X: INTEGER; . .)
.)
exports . . .;
procedure R ( . . .)
raises INTEGER_OVERFLOW;
.
.
.
implementation
If INTEGER_OVERFLOW is raised when P is invoked, the
exception is propagated
end L
.
.
.
Ch. 4
79
Case study
Compiler for the MIDI programming
language
The language is block-structured
It requires a symbol table module
that can cope with block static
nesting
We discuss here module
SYMBOL_TABLE
Ch. 4
80
SYMBOL_TABLE (vers.1)
module SYMBOL_TABLE
Supports up to MAX_DEPTH block nesting levels
uses ... imports (IDENTIFIER, DESCRIPTOR)
exports procedure INSERT (ID: in IDENTIFIER;
DESCR: in DESCRIPTOR);
procedure RETRIEVE (ID:in IDENTIFIER;
DESCR: out DESCRIPTOR);
procedure LEVEL (ID: in IDENTIFIER; L:out INTEGER);
procedure ENTER_SCOPE;
procedure EXIT_SCOPE;
procedure INIT (MAX_DEPTH: in INTEGER);
end SYMBOL_TABLE
Ch. 4
81
Ch. 4
82
SYMBOL_TABLE (vers.2)
module SYMBOL_TABLE
uses ... imports (IDENTIFIER, DESCRIPTOR)
exports
Supports up to MAX_DEPTH block nesting levels; INIT
must be called before any other operation is invoked
procedure INSERT (ID: in IDENTIFIER;
DESCR: in DESCRIPTOR)
raises MULTIPLE_DEF,
procedure RETRIEVE (ID:in IDENTIFIER;
DESCR: out DESCRIPTOR)
raises NOT_VISIBLE;
procedure LEVEL (ID: in IDENTIFIER;
L: out INTEGER)
raises NOT_VISIBLE;
procedure ENTER_SCOPE raises EXTRA_LEVELS;
procedure EXIT_SCOPE raises EXTRA_END;
procedure INIT (MAX_DEPTH: in INTEGER);
end SYMBOL_TABLE
Ch. 4
83
Ch. 4
84
Concurrent software
The case of a module defining shared data
E.g., abstract object BUFFER
module QUEUE_OF_CHAR is
GENERIC_FIFO_QUEUE (CHAR)
BUFFER : QUEUE_OF_CHAR.QUEUE
with operations
Ch. 4
85
86
Enforcing synchronization
Ensure that operations on buffer
are executed in mutual exclusion
Ensure that operations such as
if QUEUE_OF_CHAR.NOT_FULL (BUFFER)
then QUEUE_OF_CHAR.PUT (X, BUFFER);
end if;
87
Monitors
Abstract objects used in a
concurrent environment
Available in the Java programming
language
Ch. 4
88
Monitors: an example
concurrent module CHAR_BUFFER
This is a monitor, i.e., an abstract object module in a
concurrent environment
uses . . .
exports
procedure PUT (C : in CHAR) requires NOT_FULL;
procedure GET (C: out CHAR) requires NOT_EMPTY;
NOT_EMPTY and NOT_FULL are hidden Boolean
functions yielding TRUE if the buffer is not empty and not
full, respectively. They are not exported as operations,
because their purpose is only to delay the calls to PUT and
GET if they are issued when the buffer is in a state where it
cannot accept them
.
.
.
end CHAR_BUFFER
Ch. 4
89
Comments
Monitor operations are assumed to be
executed in mutual exclusion
A requires clause may be associated
with an operation
it is automatically checked when
operation is called
if the result is false, the current process is
suspended until it becomes true (at that
stage it becomes eligible for resumption)
Ch. 4
90
Ch. 4
91
92
A guardian task
loop
select
when NOT_FULL
accept PUT (C: in CHAR);
This is the body of PUT; the client calls it as if it
were a normal procedure
end ;
or
when NOT_EMPTY
accept GET (C: out CHAR);
This is the body of GET; the client calls it as if it
were a normal procedure
end ;
end select ;
end loop ;
Ch. 4
93
Real-time software
Case where processes interact with
the environment
E.g., a put operation on a shared
buffer is invoked by a plant sensor
sending data to a controller
plant cannot be suspended if buffer full!
design must ensure that producer never
finds the buffer full
this constrains the speed of the consumer
process in the controller
Ch. 4
94
TDN description
concurrent module REACTIVE_CHAR_BUFFER
This is a monitorlike object working in a real-time environment.
uses . . .
exports
reactive procedure PUT (C: in CHAR);
PUT is used by external processes, and two consecutive
PUT requests must arrive more than 5 msec apart;
otherwise, some characters may be lost
procedure GET (C: out CHAR);
.
.
.
end REACTIVE_CHAR_BUFFER
Ch. 4
95
GDN description
Module
REAC TIVE_C HAR_BUFFER
PUT
GET
96
Distributed software
Issues to consider
module-machine binding
intermodule communication
e.g., remote procedure call or message
passing
97
Client-server architecture
The most popular distributed
architecture
Server modules provide services to
client modules
Clients and servers may reside on
different machines
Ch. 4
98
Issues
Binding modules to machines
static vs. dynamic (migration)
Inter-module communication
e.g., RPC
IDL to define interface of remote
procedures
99
Middleware
Layer residing between the network
operating system and the application
Helps building network applications
Provides useful services
Name services, to find processes or
resources on the network
Communication services, such as
message passing or RPC (or RMI)
Ch. 4
100
Object-oriented design
One kind of module, ADT, called
class
A class exports operations
(procedures) to manipulate instance
objects
often called methods
101
If a is a reference to an object
a.op (params);
Ch. 4
102
A further relation:
inheritance
ADTs may be organized in a
hierarchy
Class B may specialize class A
B inherits from A
conversely, A generalizes B
A is a superclass of B
B is a subclass of A
Ch. 4
103
An example
class EMPLOYEE
exports
function FIRST_NAME(): string_of_char;
function LAST_NAME(): string_of_char;
function AGE(): natural;
function WHERE(): SITE;
function SALARY: MONEY;
procedure HIRE (FIRST_N: string_of_char;
LAST_N: string_of_char;
INIT_SALARY: MONEY);
Initializes a new EMPLOYEE, assigning a new identifier.
procedure FIRE();
procedure ASSIGN (S: SITE);
An employee cannot be assigned to a SITE if already assigned to it (i.e., WHERE
must be different from S). It is the clients responsibility to ensure this. The effect is to
delete the employee from those in WHERE, add the employee to those in S, generate
a new id card with security code to access the site overnight, and update WHERE.
end EMPLOYEE
Ch. 4
104
Ch. 4
105
Inheritance
A way of building software incrementally
A subclass defines a subtype
subtype is substitutable for parent type
Polymorphism
a variable referring to type A can refer to an
object of type B if B is a subclass of A
Dynamic binding
the method invoked through a reference
depends on the type of the object
associated with the reference at runtime
Ch. 4
106
Ch. 4
107
UML representation of
inheritance
EMPLOYEE
ADMINISTRATIVE_STAFF
TECHNICAL_STAFF
Ch. 4
108
UML associations
Associations are relations that the
implementation is required to support
Can have multiplicity constraints
TECHNICAL
_STAFF
PROJECT
1
project_member
1..*
manages
MANAGER
1
Ch. 4
109
Aggregation
Defines a PART_OF relation
TRIANGLE
POINT
Ch. 4
110
More on UML
Representation of IS_COMPONENT_OF
via the package notation
package_name
Class 1
Class 3
Class 2
Ch. 4
111
Software architecture
Describes overall system organization
and structure in terms of its major
constituents and their interactions
Standard architectures can be
identified
pipeline
blackboard
event based (publish-subscribe)
Ch. 4
112
Standard architectures
pipeline
blackboard
event based
Ch. 4
113
Domain specific
architectures
"modelviewcontroller" architecture for software
that has a significant amount of user interaction
Controller
(interact with user;
perform commands)
Model (store
data e.g. text)
Ch. 4
114
Software components
Goal
build systems out of pre-existing
libraries of components
as most mature engineering areas do
Examples
STL for C++
JavaBeans and Swing for Java
Ch. 4
115
Component integration
The CORBA (Common Object Request
Broker Architecture) Middleware
Clients and servers connected via an
Object Request Broker (ORB)
Interfaces provided by servers defined
by an Interface Definition Language (IDL)
In the Microsoft world: DCOM
(Distributed Component Object Model)
Ch. 4
116
Domain
Interfaces
CORBA
Facilities
CORBA Services
Ch. 4
117
Architectures for
distributed systems
From two tiered
Webbrowser
(client)
Client-server
to three tiered
Userinterface
(client)
Requests
for service
(database)
Requests
for service
(pages)
Decode
service
request
(2nd tier)
Ch. 4
Webserver
(server)
Application
server
(databse)
118