intro to software engineering - software design

45
Software design McGill ECSE 321 Intro to Software Engineering Radu Negulescu Fall 2003

Upload: radunegulescu

Post on 06-Sep-2014

704 views

Category:

Technology


1 download

DESCRIPTION

 

TRANSCRIPT

Page 1: Intro to Software Engineering - Software Design

Software design

McGill ECSE 321Intro to Software Engineering

Radu Negulescu

Fall 2003

Page 2: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 2

About this module

Software should be designed not just for performance, but also for maintainability! Why?

• Save on maintenance costsPost-release defect removalMinor adjustments

• Save on verification costsHigher pre-release fault detection and removal rate

• Save on development costsLower fault injection rate

• Facilitate teamworkSoftware that is more maintainable is also easier to understand

Design for maintainability requires special techniques

• Message of the textbook’s cover picture?

Page 3: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 3

Basic concept: modularity

A software system should be split into modules

• To facilitate future changeBy minimizing the scope of change

• To avoid need for future changeBy containing change within isolated modules

• To reduce development time and effortBy simplifying the systemBy postponing design decisions until optimal time, and avoiding some expensive optimizationsBy allowing comprehension and reasoning on modules and interfaces

Page 4: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 4

Modularity

Two main criteria:

• Cohesion: a measure of tightness of relationships within a module

• Coupling: a measure of tightness of relationships among modules

Tradeoff:

• Strong cohesion: Focused modulesMore granularity

• Loose coupling:Isolated modulesLess granularity (to avoid split dependencies)

• Optimum: around 7+-2 modules at each level of abstractionThis holds for large modules (subsystems) and small modules (individual objects or routines) alikeThis is just an estimate, not an absolute rule

Page 5: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 5

Cohesion

“Single-minded functionality”: operations in a module should be strongly related

Types of cohesion:

(HIGH)

• Functional: perform one function only

• Communicational: use the same data

• Sequential: an incomplete sequence of causally-related actions

• Procedural: sequence of non-causally-related actions

• Temporal: actions that are performed at the same time

• Logical: decision branches

• Coincidental: no discernable relationship

(LOW)

Page 6: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 6

Strong cohesion

Heuristics

• Partition the system according to dependency clusters

• Isolate presentation, data management, and processingMVC architectures

• Isolate control from workFocus on control-only or work-onlyHigh-cohesion “control-only” modules

Dispatching eventsStartup and shutdown routines (delegate the individual tasks)

• Isolate main functionality from auxiliary functionalityException throwingGarbage collection

• A complex name usually indicates poor cohesionSplit “getAndSet” routines

Page 7: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 7

Example of strong cohesion

From [BD]:

Alternative

Decision

Criterion

subtasks

*SubTask

ActionItem

DesignProblem

Task

assesses

solvableBy

resolvedBy

based-on

* * *

implementedBy

DecisionSubsystem

RationaleSubsystem

PlanningSubsystem

Page 8: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 8

Decoupling

“Aversion to interaction”: different modules should be detached

Types of coupling:

• Simple-data ("normal"): non-structured parameter list

• Data-structure ("stamp"): structured parameter

• Control: select a callee task by a flag parameterLogical cohesion

• External: the program is tied to a particular device or environment => non-portable

• Global-data ("common"): two routines access the same global dataAt least make it read-only

• Pathological ("content"): use internal data of a different moduleE.g. via pointers

Page 9: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 9

Loose coupling

Heuristics:

• Small interfaces: few parameters

• Adapted interfaces: convenient for the callee

• Flexible interfaces: convenient for many callersOrthogonality

• Visible interfaces: no direct access to protected data

• Avoid pathological coupling: pass parameters through interfacesfloat[][] A;x = det(A);

• Avoid stamp coupling: decompose bundles of parameters into basictypes or very-high-cohesion parameters (e.g. events)

• Avoid external coupling: use IDEs that produce portable code

• Avoid global-data coupling: In object-oriented programs, use “get” and “set” methods to read and modify object attributes

Page 10: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 10

Example of loose coupling

Adapted from [BD]: change from binary tree to linked list

• Parse tree for a + b + c

add1:Nodeadd2:Node

c:Nodeb:Nodea:Node

add:Nodec:Nodeb:Nodea:Node

Sharing through attributesclass Node {Node left;Node right;String name;

}

Sharing through operationsclass Node {

Enumeration getArguments();String getName();

}

Sharing through attributesclass Node {

Node next;String name;

}

Sharing through operationsclass Node {

Enumeration getArguments();String getName();

}

Page 11: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 11

Example of bad modularity

/* If 'direction' is 0, input n rowsinto array 'lines';otherwise output n rows from array 'lines'.Pre: 0 <= n <= length(lines).

*/in_out (

int n, /* number of rows, input or output */int direction /* control flag: 0 = in, 1 = out */

) {int i;for (i = 0; i < n; i ++) {

if (direction == 0) {read one input row into lines[i];

} else {write lines[i];

} }

}

/* Read n lines of input.Output the lines in sorted order.Pre: 0 <= n <= length(lines).

*/input_sort_echo(

int n /* number of rows to be sorted */) {

int i, j;in_out(n, 0);for (i = 0; i < n - 1; i ++) {for (j = i + 1; j < n; j ++) {if (lines[j] <= lines[i] alphabetically) {copy string lines[j] into string temp;copy string lines[i] into string lines[j];copy string temp into string lines[i];

}}

}in_out(n, 1);

}

Page 12: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 12

Improving modularity

Global-data coupling:

• Both routines access array lines

• Fix: the access to array lines and string temp can be made explicit in the routine interfaces

Logical cohesion:

• The same routine (in_out) performs unrelated operations

• Fix: split into an input routine and an output routine

Communicational or temporal cohesion:

• The same routine (input_sort_echo) controls the flow and does the sorting

• Fix: call sorting as a sub-routine

Page 13: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 13

Example of improved modularity

/* Input n rows to 'lines';Pre: 0 <= n <= length(lines). */

in(int n, /* number of rows to be input */StringArray lines /* storage */

) {int i;for (i = 0; i < n; i ++) {

input lines[i]; /* read one row */}

}

...sort(

int n, /* number of rows to be input */StringArray lines /*

) { ...

...out(

int n, /* number of rows to be input */StringArray lines /*

) {...

/* Read n rows and output them sorted.Pre: n >= 0

*/input_sort_echo(

int n /* number of rows to handle */) {

Declare and allocate StringArray lines;in(n, lines);sort(n, lines);out(n, lines);

}

Page 14: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 14

Design process

Design: blackbox model full-detail (clearbox, whitebox, glassbox)

• Choose among several alternativesConsider solutions permitted by the analysis model

Heuristics, patternsConstraints, invariants

Optimize design goals tradeoffsSelect and prioritize goals: maintainability, usability, performance, etc.

• Iterate through the designWhy?

Brainstorming and consolidationPrototypes to clear out technical risksSeveral levels of abstractionSeveral viewpoints, design goalsFixing defects

Know where to stopReview criteria

Page 15: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 15

Overview of software design

System-level

• Using the analysis model as a starting point, take high-level decisions to optimize the selected design goals

Object-level

• “Close the gap” between the architecture model and the deployment platform

Detailed

• Organize and build code in a way that supports change and reasoning

Specialized design

• UI design

• Function-oriented design

• Real-time, etc.

Page 16: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 16

System-level design

System-level design typically comprises the following activities:

• Identifying design goals and constraints

• Defining the architectureDecomposing the system into subsystemsSelecting system-wide conventions and policies:

PersistencySecurityGlobal control flowBoundary conditions: start-up, shut-down, error handling

• Selecting reusable components, libraries, etc.

• Mapping to hardware

Page 17: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 17

Object design

The following activities are typically performed at this level:

• Identifying design objects: implementation-specific classes

• Service specification: precisely describe interfaces

• Component selection: find pre-made parts that are suitable for the functionality of the system

• Object model restructuring: optimize maintainabilityReduce multiplicityImplement binary associations as referencesMerge similar classesCollapse trivial classes into attributesSplit complex classes

• Object model optimization: optimize performanceUse different algorithms / data structuresAdd or remove redundant associationsAdd derived attributes“Open up” the architecture

Page 18: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 18

Design goals

First thing: determine goals and priorities

• Include viewpoints of several stakeholders

• See [BD, sect.6.4.2] for a comprehensive list of software design goals

• Relative importance varies depending on the nature of the application

Page 19: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 19

Design goals

End-user / customer / sponsor Developer / maintainerscope xlow cost/effort x xlow dev. time x xlow defect rate x xmodifiability xcomprehensibility x xreliability xrobustness xuser-friendliness xdocumentation x xreusability xadaptability xportability xbackward compatibility xperformance xmemory efficiency x

Page 20: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 20

Performance measures

Running time is not a single, well-defined measure

• Consider all input data and internal non-determinism

• Worst-case: maximum valueE.g. car airbag controller: worst-case is criticalPolling: time = (#sensors) * (time per sensor) + (alarm time)Interrupts: time = (interrupt path length) * (hub delay) + (alarm time)

• Average-case : weighted by operation frequency (operational profile)E.g. text editor: average-case is more important than worst-caseE.g. videophone image compression: both worst-case and average-case are important

• Amortized: mean taken over an operating cycleE.g. the average number of bit flips in an n-bit number

Answer: 2! (Why?)

Page 21: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 21

Performance measures

Many performance measures

• Latency vs. throughputE.g., an IDE that does background compilation performs more work to improve average latencyE.g., a web service might have a fixed limit on the response time (latency), and optimize the maximum number of simultaneous requests (throughput)

• Memory requirementsData storage: scalability, garbage collection

• Number of expensive operations (function calls, multiplications, etc.)

• Number of accesses to communications, external storage, or I/O resources

E.g. a trip planner might allow increased response time to minimize wireless communication time

Page 22: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 22

Design tradeoffs

Typical design tradeoffs:

• Rapid development vs. scope

• Performance vs. maintainabilityOrders of growth

• Performance vs. portability

• Backward compatibility vs. comprehensibility

• Cost, delivery time vs. robustness, reusabilityNot to be confused with cost vs. other quality parameters

• Space vs. speedWhy operating systems, IDEs, etc. will fill up hard drives of any sizes?

Not easily traded:

• Quality vs. effortLow defect rate, maintainability, comprehensibility, documentationEarly in the project: non-tradeableLate in the project: tradeable to a small extent

• Delivery time vs. staffingOnly early in the projectBrooks’ law: adding people to a late project only makes it later

Page 23: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 23

Software architecture

Architectural design should address:

• Subsystem decomposition

• System-wide policiesData organizationControl flowCommunication protocolsError handlingMapping to hardwareSecurity

• NOT development methodology issues, such as object-orientation vs. function-orientation

Page 24: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 24

Basic definitions

Subsystems

• Parts of a system

• Can be developed and changed independently (more or less)

• Example: UI evolves independently from business logic

Services

• A service provided by a subsystem = a set of operations of that subsystem that share a common purpose

• Examples: download, upload, notification, management, …

Interfaces

• An interface of a subsystem = a black-box view of that subsystemAs seen by an actor or by another subsystem

• API: operations, signatures, and specificationsSignature = parameter types, return typeExample: doGet method of HttpServlet class

���������������������������������������������������������������������������� ���������������� ���������������� ���������������� ���������������� �������������������� ����������������� ����������������� ����������������� ����������������� ����������������������������������������������������������������������������������������������������������������������������������������������������������������

Page 25: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 25

Defining the architecture

Decomposition into subsystems

• HeuristicsUse variants of Abbott’s lexical rules: nouns, verbsIdentify groups of objects involved in use cases

Encapsulate functionally related classes - Facade patternIsolate scope overlaps among use cases

Create dedicated subsystems for moving data among subsystemsCreate a separate subsystem for the user interface

Encapsulate legacy code - Adaptor pattern

Page 26: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 26

Layers and partitions

Different ways of decomposing the system:

• Layering: each subsystem provides a level of abstractionClosed architecture: each layer can access services from the layer immediately below it. E.g. ISO OSIOpen architecture: each layer can access services from any layers below it E.g. Motif toolkit for X11

• Partitioning: peer subsystems with as few dependencies as possible

• Not a clear distinction between layering and partitioning

A B C

D E

F G H

Page 27: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 27

Common architectures

Design the data first, then the control

• During analysis, may assume objects run whenever needed

• During design, the object behavior should be determined so that the object does indeed run whenever needed

Types of data organization schemes:

• Repository

• Model-view-controller (“architecture”, “framework”, “pattern”)

• Client/server

• Peer-to-peer

• Pipe-and-filter / data flow

Types of control flow:

• Centralized

• Event-driven

• Thread-based

Page 28: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 28

Repository architecture

Subsystems interact by sharing data in a central repository

The repository may also implement control flow

• Serialize concurrent accesses of processing subsystems

• Activate subsystems depending on state of data (“blackboard”)

E.g. DBMS, compilers [BD], various CAD tools

LexicalAnalyzer

SyntacticAnalyzerSemanticAnalyzer

CodeGenerator

SourceLevelDebugger SyntacticEditor

ParseTree SymbolTable

Compiler

Repository

Optimizer

Page 29: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 29

Repository architecture

Pros:

• Decoupled subsystems; easy to add new ones

Cons:

• Repository may become a bottleneck

• Strong coupling between each subsystem and the repository

Page 30: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 30

Model-view-controller

A.k.a. MVC

Partition data representation (model), presentation (view), and control

• One of the first design patterns: model state updates are reported to all views

Refined to “observer pattern” (will see later)May use “Listener” objects in Java

• Special case of the repository architecture, if the model is considered to be the data repository

Controller

Model

subscribernotifier

initiator

*

repository1

1

*

View

Page 31: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 31

Model-view-controller

Pros:

• Allows independent change of model, view, and controller

• Allows subscription at runtime

• Isolates variability, as the views are less stable than the model

Cons:

• The model may become a performance bottleneck

Page 32: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 32

Client-server

Servers provide services to clients

• E.g. central database

• E.g. communication systemsWeb server; DNSMail server; news server; ...

• Suitable for distributed systems that process large amounts of dataWhy?

Page 33: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 33

Client-server

Three-tiered architecture:

Browser

WebServer

Servlet

DataBase

JDBC

http request

service

query

SQL query table

result set

string

web page

Page 34: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 34

Peer-to-peer

Peer-to-peer:

• Generalize client-server systems

• Each subsystem can request and provide servicesE.g. a database that can also notify the application

• More difficult to designMany possible interleavings of messages/service requestsMany possible modes of failure in concurrent/distributed systems

DeadlockUnfairness/starvationLivelock/divergence...?

Process1

Resource1

Resource2

Process2

1:req

5:req 3:req4:ack

2:ack

6:req

Page 35: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 35

Pipe-and-filter

Filters: processing subsystems

• Executing concurrently

Pipes: associations between filters

• Data transfer

• Synchronization

E.g. UNIX shell [BD]

ps grep sort more

Page 36: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 36

Centralized control

Two types

• Call-return (procedure-driven): sequential subroutine callsRigid => easy to debug, but locks resources

• Manager: one component is designated to control a concurrentsystem

E.g.: a repository database that can signal changesFlexible => Better real-time response, efficiencyMore difficult to design => interleaving, modes of failure

Page 37: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 37

Event-driven control

Two types

• Interrupt-drivenInterrupts are serviced immediately (according to priority)Offers execution time bounds, hence good for real-time systems

• BroadcastEvents are broadcast to several listeners, who will handle them when they canBetter modularity, but no time boundsUsually combined with the MVC architecture

Page 38: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 38

Broadcast events example

Events are key to implementing graphical user interfaces

• The broadcast method of the source may be invoked automatically upon occurrence of an event

Example: ActionEvents are emitted by Button objects

addActionListener(ActionListener)

removeActionListener(ActionListener)

...

ActionListener

actionPerformed(ActionEvent)

MyListener

actionPerformed(ActionEvent e)

ActionEvent

getActionCommand()getSource()

e

* 1

1

*

1 *

Button

Page 39: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 39

Broadcast events example

Example: Mouse events are emitted by a Component object

• Applets and other subclasses of Component inherit its methods

• Mouse movement events are sent to a different listener (MouseMotionListener)

MouseListener

mouseClicked(MouseEvent)

mousePressed(MouseEvent)

...

MyListenerMouseEvent

Point getPoint()setPoint(Point)

* 1

1

*

1 *

mouseClicked(MouseEvent)

mousePressed(MouseEvent)

...

addMouseListener(MouseListener)

addMouseMotionListener(MouseMotionListener)

Component

...

Applet

1 *

MouseMotionListener

Page 40: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 40

Using events

Events ensure communication between source and listener while effectively decoupling the functionality of source and listener

• None needs to know the details of the other

• The connection can be made and cancelled dynamically

Event queues may be added to further decouple the timing of source and listener

• Source and listener may operate at different rates

Page 41: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 41

Thread-based control

Thread-based

• Several streams of execution that respond to different users, different stimuli, different events, etc.

• Example: servletsService method

• Issue: mutual exclusionCommunication through shared variables“synchronize”

Page 42: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 42

Threads example

class MyThread extends Thread {int k = 0; // the data managed by the Threadint m_id; // unique ID for each Thread

public MyThread(int id) {m_id = id;

}

// print and update the "data", i.e., integer k// invoked whenever the system executes the Thread public void run() {

for(;;) { // foreverSystem.out.println("Thread " + m_id + ": " + k);k++;

}}

}

Page 43: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 43

Thread-based control

• May use queues to further decouple request generation from request handling

*

Stimulus Thread**

Event

Stimulus Thread*

Event queue

Event*1

*1

Stimulus Thread* *

Page 44: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 44

Using threads

Threads are used for modularity, not performance

• (Unless the OS scheduler is clever enough to map them to separate processors)

• Decouple different user workflowsDifferent usersDifferent applications of same user

• Tracking different actors

• Mapping to different hardware

• Avoid concurrency

• Handle concurrency with mutual exclusion (synchronize)

Page 45: Intro to Software Engineering - Software Design

McGill University ECSE 321 © 2003 Radu Negulescu Introduction to Software Engineering Software design—Slide 45

References

Modularity

• BD 6.3.3

• McConnell 5.3, 5.4

System-level design

• BD 6.3.1-6.3.5, 6.4.1-6.4.5, 6.4.8-6.4.10

Architectural options

• BD 6.4.7