You are on page 1of 71

Design Principles I - Correctness and

Robustness

• Introducing two design Principles:


• Correctness
• Robustness

Requirements
Analysis
Design
Framework Architecture Detailed Design

Key: = less affected Implementation

Adapted from Software Design: From Programming to Architecture by Eric J. Braude (Wiley 2003), with
permission.
Correctness Interfaces Modularization Robustness Design Details 2/24

Correctness

Correctness
Goal: That each artifact satisfies designated
requirements, and that together they satisfy all
of the application’s requirements.
Correctness Interfaces Modularization Robustness Design Details 3/24

Approaches to correctness
• How can we know that a design is correct or even sufficient?
• Approaches to correctness
• Informal approaches
• Formal approaches

• Informal approaches: to be convinced that the design covers the


required functionality.

• Formal approaches
• Formal methods for establishing correctness involve applying
mathematical logic to analyzing the way in which the variables change
• Formal methods are usually applied when the design enters the
detailed design
Correctness Interfaces Modularization Robustness Design Details 4/24

Informal approaches to
correctness
• Correctness by Informal Methods
Simplify and modularize designs until they are
convincing.

• Informal Approaches
• Informal approaches are based on the common sense idea
that before we can proclaimed a design to be correct, we
have to understand it completely.
• Informal approaches require that design must be
• Readable (to enhance understanding)
• Modular (to deal with complexity)
Correctness Interfaces Modularization Robustness Design Details 5/24

Sufficient Designs: Terminology and Rationale


A design sufficient
Minimum
to implement the a correct design
goal: Sometimes
requirements.
called …
It follows that …
the design must be
entirely understandable

A common way to achieve


this is to make …
the design
very modular
Correctness Interfaces Modularization Robustness Design Details 6/24

Formal approaches to correctness


• Formal approaches
• Keeping variable changes under tight control
• It can be achieved through invariants
• Invariants are unchanging relationships among variable
values
• Invariants used at class level are class invariants
• Examples:
• “length>=0”
• “length * breadth == area”
Correctness Interfaces Modularization Robustness Design Details 7/24

Invariants for Class Automobile


-- with variables mileage, VehicleID, value,
originalPrice, and type:
1) mileage > 0
2) mileage < 1000000
3) vehicleID has at least 8 characters
4) value >= -300
• ($300 is the disposal cost of a worthless automobile)
5) originalPrice >= 0
6) ( type == “REGULAR” && value <= originalPrice ) ||
• ( type == “VINTAGE” && value >= originalPrice )
Correctness Interfaces Modularization Robustness Design Details 8/24

Formal approaches to correctness


(cont.)
• Some guidelines for achieving correctness at coding
level
• Make variables private

• Change the variables values only through public


accessor methods

• Accessors can be coded to maintain invariants


Correctness Interfaces Modularization Robustness Design Details 9/24

Interfaces to modules

• Interfaces: collections of function prototypes:


Make designs more understandable.

• Modularity
• Modularization is key to assess the correctness of a
design
• A module can be either a class or a package of classes
• An interface is a set of functions forms (or prototypes).
Correctness Interfaces Modularization Robustness Design Details 10/24

Interfaces to modules
• Interfaces to classes
• When a class supports many methods, it is often
beneficial to group them into several interfaces
Shipment
• Grouping allows reuse setVehicle()
perishable()
getWidth()
printRoute()
describeType()
getLength()
getDuration()
setType()
Correctness Interfaces Modularization Robustness Design Details 11/24

Introducing Interfaces
Dimensions TransportationMeans GoodsType
getWidth() getDuration() describeType()
getLength() setVehicle() setType()
getWeight() printRoute() perishable()

Original form
Shipment Shipment
setVehicle()
perishable()
getWidth() Forms using
printRoute() interfaces Dimensions
describeType()
getLength() Shipment TransportationMeans
getDuration()
setType() GoodsType
Correctness Interfaces Modularization Robustness Design Details 12/24

Interfaces to modules
• Interfaces to Packages
• Interface to package is different idea than an interface to
a class

• Provide an interface for a designated object of a class in


the package or

• Define a class in a package and define its interface as


static methods
Correctness Interfaces Modularization Robustness Design Details 13/24

Package Interfaces
purchases

Pricing
Furniture

«singleton»
Clothing PurchasesIF Selection

Appliance ClothingTryout
Correctness Interfaces Modularization Robustness Design Details 14/24

Example of Package Interfaces


chatServer Conversation-
services
Conversation

ConversationManager

ServerComm Participant-
services chatClient

billing Display
Message-
Accounting Bill reception ClientComm

Financial
Correctness Interfaces Modularization Robustness Design Details 15/24

Modularization
• To modularize an object-oriented
application
• Create packages at the higher level
• Create classes at the lower level

• Choosing classes (Two kinds of classes)


• Domain classes
• classes that pertain to the specific application under design.
• Can be obtained from the sequence diagrams of use cases.
• Non-domain classes
• generalization of domain classes
Correctness Interfaces Modularization Robustness Design Details 16/24

Domain vs. Non-Domain Classes


• Domain classes: Particular to the application
• Examples: BankCustomer, BankTransaction, Teller
• Typically not GUI classes
• Sufficient to classify all requirements

• Non-Domain classes: Generic


• Examples: abstract classes, utility classes
• Arise from design and implementation considerations
Correctness Interfaces Modularization Robustness Design Details 17/24

Modularization
• Choosing packages
• Essential part of choosing an application’s architecture
• Decompose application into a set of packages (typically
3 to 10)
Correctness Interfaces Modularization Robustness Design Details 18/24

Robustness

• The ability to handle anomalous situations


• Incorrect user input
• Faulty data communication
• Developer errors
• Verifying Input.
• Robustness is promoted by verifying data values before using
them.
• Check all inputs for constraints. It can include:
• Type verification, Preconditions, Invariants, Postconditions

• Initialize variables and objects at declaration/ creation


time improve robustness
Correctness Interfaces Modularization Robustness Design Details 19/24

Sources of Errors
• Robustness --- ability to handle anomalous
situations even in the presence of errors
• Sources of error:
• Faulty input
• User input
• Input, not from users
• Data communication
• Function calls made by other applications

• Developer errors
• Faulty design
• Faulty implementation
Correctness Interfaces Modularization Robustness Design Details 20/24

Constraints on Parameters
Example:
int computeArea( int aLength, int aBreadth ) { … }
❑Capture parameter constraints in classes if feasible
int computeArea( RectangleDimension a RectangleDimension )
❑Specify all parameter constraints in method comments
aLength > 0 and
aBreadth > 0 and
aLength >= aBreadth
❑Callers obey explicit requirements on parameters
• Problem is method programmers have no control over callers
❑Check constraints first within the method code
if( aLength <= 0 ) ……
• Throw exception if this is a predictable occurrence
• Otherwise abort if possible
• Otherwise return default if it makes sense in context
• And generate warning or log to a file
Correctness Interfaces Modularization Robustness Design Details 21/24

Wrapping Parameters (to handle constraints)


Replace int computeArea( int aLength, int aBreadth ) {..}
with int computeArea( Rectangle aRectangle ) {..}

-- where class Rectangle


{…
Rectangle( int aLength, int aBreadth )
{ if( aLength > 0 ) this.length = aLength;
else …..
}
…}
Correctness Interfaces Modularization Robustness Design Details 22/24

Design Details
• How much is enough?
• Most detailed design provide
• Class, sequence, state, and activity models
• Provide activity diagram or pseudocode for
complex methods only
• Code before design?
• Depends of the nature of the task and the experience of
the programmer.
• Design details through a graph
Correctness Interfaces Modularization Robustness Design Details 23/24

How Much Design Detail Before Initial Coding?


100%
Inexperienced
Recommended designer
% of design
detail before
starting to
code

Diminishing ability
of designer to
envisage
Experienced consequences of
designer design decision.
Very simple 0% Very complex
Type of application
Correctness Interfaces Modularization Robustness Design Details 24/24

Summary of This Chapter


❑ Correctness of a Design or Code
• Supports the requirements
• In general, many correct designs exist

❑ Robustness of a Design or Code


• Absorbs errors
• -- of the user
• -- of developers
• is promoted by enforcing intentions.
Teacher: Dr. Khurram Zeeshan Haider
Dept. of Software Engineering, GCUF
Design Principles II

• Flexibility, Reusability, &


Efficiency

Adapted from Software Design: From Programming to Architecture by Eric J. Braude


(Wiley), with permission.
Flexibility Reusability Efficiency Trade-off between Principles 2/24

Aspects of Flexibility

Flexible design implies a design that easily can accommodate the


changes
Anticipate..
❑ … adding more of the same kind of functionality
Example (banking application): handle more kinds of accounts without having
to change the existing design or code
❑ … adding different functionality
Example: add withdraw function to existing deposit functionality
• … changing functionality
Example: allow overdrafts
Flexibility Reusability Efficiency Trade-off between Principles 3/24

Registering Website Members

WebSite members 0..n


Member
register()

Example: Registering members at


a web site (Design 1)

What’s wrong with this design?


Flexibility Reusability Efficiency Trade-off between Principles 4/24

Registering Website Members Flexibly


members 0..n
WebSite Member

YMember XMember StandardMember

Example: Registering members at


a web site (Design 2: a flexible
design)
Flexibility Reusability Efficiency Trade-off between Principles 5/24

Adding Functionality to an Application

Alternative Situations
• Accommodate adding new kinds of functionality
• Adding functionality to an application: alternative
situations: Within the scope of …
1. Within the scope of a list of related functions
Example: add print to an air travel itinerary functions
2. Within the scope of an existing base class
Example: add “print road- and ship- to air itinerary ”
3. Within the scope of: neither
Example: add “print itineraries for combinations of air, road
and ship transportation”
Flexibility Reusability Efficiency Trade-off between Principles 6/24

Adding Functionality When a Base Class Exists

Trip
SomeApplicationClass
printItinerary()

Method(s) call StandardTrip


printItinerary() printItinerary()

Case 1: Case 1 can be handled by adding the new


method to an existing set of methods of a class
Add method print() to the class Itinerary.
Flexibility Reusability Efficiency Trade-off between Principles 7/24

Adding Functionality Through a Base Class


Trip
SomeApplicationClass
printItinerary()

StandardTrip LandTrip SeaTrip


printItinerary() printItinerary() printItinerary()

Case 2: Adding functionality when a base class


exists
Flexibility Reusability Efficiency Trade-off between Principles 8/24

Additional Type of Flexibiliy


Flexibility Aspect: ability to … Described in …
… create objects in variable
configurations determined at “Creational” design patterns
runtime
… create variable trees of objects or
other structures at runtime “Structural” design patterns

… change, recombine, or otherwise


capture the mutual behavior of a set “Behavioral” design patterns
of objects
… create and store a possibly
complex object of a class.
… configure objects of predefined Component technology
complex classes – or sets of classes
– so as to interact in many ways
Flexibility Reusability Efficiency Trade-off between Principles 10/24

Reusability of function design


• Simple methods

• Guidelines for designing reusable methods


– Reusable methods must be defined completely

– Reusable methods must be independent of their


environment, e.g., Static methods
• Makes the design looser coupling, less coherent and less object-
oriented.

– Name of a reusable method must be reflective of its


functionality
Flexibility Reusability Efficiency Trade-off between Principles 11/24

Making a Method Re-usable


❑ Specify completely
– Preconditions etc
❑ Avoid unnecessary coupling with the enclosing class
– Make static if feasible
– Include parameterization
• i.e., make the method functional
• But limit the number of parameters
❑ Make the names expressive
– Understandability promotes re-usability
❑ Explain the algorithm
– Re-users need to know how the algorithm works
Flexibility Reusability Efficiency Trade-off between Principles 12/24

Making a Class Re-usable


❑ Describe the class completely
❑ Make the class name and functionality
match a real world concept
alternatives

❑ Define a useful abstraction


– attain broad applicability
❑ Reduce dependencies on other classes
– Elevate dependencies in hierarchy
Flexibility Reusability Efficiency Trade-off between Principles 13/24

Reducing Dependency Among Classes


Replace …

Student Course

With !!! What do you think?

Increase the reusability of a class by reducing its dependencies.


Flexibility Reusability Efficiency Trade-off between Principles 14/24

Leveraging Inheritance, Aggregation and Dependency

Customer
computeBill()
(1) Leveraging inheritance

RegularCustomer
computeBill()
Customer (2) Leveraging
computeBill() aggregation
Customer Bill
computeBill() compute()

Customer Orders
(3) Leveraging
computeBill( Orders ) value()
dependency
Flexibility Reusability Efficiency Trade-off between Principles 15/24

Efficiency
• Applications must execute required
functionality within required time constraints

• Two dimensions of efficiency: time and space

• Ideally optimize a design for both time and


space
Flexibility Reusability Efficiency Trade-off between Principles 16/24

Space-Time Trade-offs
Time to process one item

Typical target

Space
Flexibility Reusability Efficiency Trade-off between Principles 17/24

Basic Approaches to Time Efficiency


❑ Design for Other Criteria, Then Consider Efficiency
– Design for flexibility, reusability , …
– At some point, identify inefficient places
– Make targeted changes to improve efficiency
❑ Design for Efficiency From the Start
– Identify key efficiency requirements up front
– Design for these requirements during all phases
❑ Combine These Two Approaches
– Make trade-offs for efficiency requirements during design
– Address remaining efficiency issues after initial design
Flexibility Reusability Efficiency Trade-off between Principles 18/24

Speed efficiency
• Real-time applications are the
most demanding in terms of
speed

• Profiler--- an application that


tracks resource usage during
program execution
Flexibility Reusability Efficiency Trade-off between Principles 19/24

Impediments to Speed Efficiency


• Loops
– while, for, do (think about sorting algorithms)
• Remote operations
– Requiring a network
• LAN
• The Internet

• Function calls
– -- if the function called results in the above
• Object creation
Flexibility Reusability Efficiency Trade-off between Principles 20/24

Trade-off Between
Number of Remote Calls and
Volume retrieved Volume Retrieved at Each Call
at each access

Typical target

Number of remote accesses


Flexibility Reusability Efficiency Trade-off between Principles 21/24

Attaining Storage Efficiency


❑ Store only the data needed
– Trades off storage efficiency vs. time to extract and re-integrate

❑ Compress the data


– Trades off storage efficiency vs. time to compress and
decompress

❑ Store in order of relative frequency


– Trades off storage efficiency vs. time to determine location
Flexibility Reusability Efficiency Trade-off between Principles 22/24

Trading off Robustness, Flexibility, Efficiency and


Reusability

1A. Extreme Programming Approach


- or - Design for sufficiency only
1B. Flexibility-driven Approach
Design for extensive future requirements
Reuse usually a by-product
2. Ensure robustness
3. Provide enough efficiency
Compromise re-use etc. as necessary to
attain efficiency requirements
Flexibility Reusability Efficiency Trade-off between Principles 23/24

A More Flexible Design for Calculator Application

Existing Design New Design

Calculator CalcDisplay
solicitNumAccounts() display()
CommandLineCalculator
main()
executeAdditions() CalcOperation
solicitNumberAccounts() execute()
getAnInputFromUser()
interactWithUser()

Add Multiply Divide


Flexibility Reusability Efficiency Trade-off between Principles 24/24

Summary of This Chapter


❑Flexibility
– == readily changeable
We design flexibly, introducing parts, because change and
reuse are likely.

❑Reusability
– in other applications
❑Efficiency
– in time
– in space
Object Orientation
Objectives

SWE 316: Software Design and Architecture


Object Orientation Classes and Objects Example Polymorphism Interfaces Things to be considered 2/24

Before Object Orientation


Real world concepts
Skljkvjkvjfkavjafkk
saovjsdvjfvkfjvkfjk
Skljkvjkvjfkavjafkk
saovjsdvjfvkfjvkfjk
Skljkvjkvjfkavjafkk
saovjsdvjfvkfjvkfjk
Skljkvjkvjfkavjafkk
saovjsdvjfvkfjvkfjk

Software
Design
Entities

SWE 316: Software Design and Architecture


Object Orientation Classes and Objects Example Polymorphism Interfaces Things to be considered 3/24

Goals of Object Orientation


AJAX BANK
How Do We Express
Ourselves?
"Customers Montague and
Susan entered the Ajax bank
and were served by teller
Andy ..... "

SWE 316: Software Design and Architecture


Object Orientation Classes and Objects Example Polymorphism Interfaces Things to be considered 4/24

How We Express Ourselves


"Customers
Montague and Susan
entered the Ajax
CLASSES OBJECTS
bank and were
served by teller Andy
..... "
Note that Java code convention reverses this capitalization.

SWE 316: Software Design and Architecture


Object Orientation Classes and Objects Example Polymorphism Interfaces Things to be considered 5/24

Object Orientation
Real world concepts Skljkvjkvjfkavjafkk
saovjsdvjfvkfjvkfjk
Skljkvjkvjfkavjafkk
saovjsdvjfvkfjvkfjk
Skljkvjkvjfkavjafkk
saovjsdvjfvkfjvkfjk
Skljkvjkvjfkavjafkk
saovjsdvjfvkfjvkfjk

Direct
correspondence

Customer Transaction Account


getFirstName() execute() getDetails()
Software design entities
Graphics reproduced with permission from Corel.

SWE 316: Software Design and Architecture


Object Orientation Classes and Objects Example Polymorphism Interfaces Things to be considered 6/24

Benefits of OO

Object orientation provides a direct


mapping between concepts and code

SWE 316: Software Design and Architecture


Object Orientation Classes and Objects Example Polymorphism Interfaces Things to be considered 7/24

Classes and Objects

Real world Class Class


in Design in Source code
(UML notation) (Java)
class AjaxCustomer
AjaxCustomer { . . . .
}

class PermissionToPay
Mental
PermissionToPay { . . . .
concept }

SWE 316: Software Design and Architecture


Object Orientation Classes and Objects Example Polymorphism Interfaces Things to be considered 8/24

The Members of a Class


Class model Non-static variable: One Objects of Auto
version for every object

Auto aliceBrownBMW:Auto
public int vehicleID … 33024
protected int mileage …
private myPrivateVariable … … mileage
static int numAutosMade … Static variable: 12390924850984
One version only numAutosMade
Subclasses
have these
members
myToyota:Toyota jaynesCar:Auto
too 2105 83402
mileage mileage
… …
Toyota

SWE 316: Software Design and Architecture
Object Orientation Classes and Objects Example Polymorphism Interfaces Things to be considered 9/24

Attribute Types
 Naming:
 fixed for each object Auto
 distinguishes individuals
vehicleID
 Descriptive:
 varies through life of object mileage
 Referential:
owner
 ties instance of one class to instance(s) of another
 == aggregation

SWE 316: Software Design and Architecture


Object Orientation Classes and Objects Example Polymorphism Interfaces Things to be considered 10/24

Classes and Objects


 A class expresses a concept such as
“HondaCivic.”
 An object is an instance of a class such as
“the Honda Civic with vehicle ID
89R783HJD894.”

SWE 316: Software Design and Architecture


Object Orientation Classes and Objects Example Polymorphism Interfaces Things to be considered 11/24

The Clients of a Class


class Customer
{...
String getName() { … }
int computeBalance() { … }
...
class AjaxAssets
}
{...
int computeAssets()
class AjaxWebsiteGenerator { ...
{...
void makeProfile( Customer c )
Customer c = customers[ i ];
{… assets += c.computeBalance();
String name = c.getName() … ...
} }
... ...
} Client of Customer Client of Customer
}
SWE 316: Software Design and Architecture
Object Orientation Classes and Objects Example Polymorphism Interfaces Things to be considered 12/24
Why OO is Useful for Application
Development?
❑ Class (Sec 2.2.1) ❑ Inheritance (Sec 2.3.1)
 basic motive of Object  capturing the way
Orientation concepts occur in
 identifying parts that hierarchy
corresponds to the real
world

❑ Polymorphism (Sec
❑ Instantiation (Sec 2.3.2)
2.2.2)  capturing use of single
 creating instances of action word to represent
encapsulated concepts different things,
depending on context
SWE 316: Software Design and Architecture
Object Orientation Classes and Objects Example Polymorphism Interfaces Things to be considered 13/24

Requirements For e-Mail Creation Example


1. Summary: Page 1 of 4
Produces e-mail text for various types of customers.
2. Detailed requirements
2.1 The application displays choices to the console, as
shown in figure 2.13.
2.2 For customers delinquent more than 90 days, the e-
mail message generated is the statement shown in figure
2.12.

SWE 316: Software Design and Architecture


Object Orientation Classes and Objects Example Polymorphism Interfaces Things to be considered 14/24

Requirements For e-Mail Creation Example


Page 3 of 4

2.3 All non-delinquent customers receive a tailored


e-mail messages as follows.
2.3.1 Mountain customers:
This month we have a special on West Face tents.
Only $700.
... lots more output specialized to mountaineering
customers ...
2.3.2 Regular customers:
All items are marked down 20% for this month
only.
... lots more output for regular customers ...
SWE 316: Software Design and Architecture
Object Orientation Classes and Objects Example Polymorphism Interfaces Things to be considered 15/24

Requirements For e-Mail Creation Example


Page 4 of 4
2.4 The e-mail is to be displayed on the console.

3. Future enhancements

We anticipate that the text is likely to change


frequently, and that new kinds of customers are
likely to be specified, each with its own new set of
requirements.

SWE 316: Software Design and Architecture


Object Orientation Classes and Objects Example Polymorphism Interfaces Things to be considered 16/24

Disadvantages of Branching
 Code for each case not cohesive
(“cohesive”: forms a comprehensible unity)
 All types of customers coded together in single class
Expensive to …
 … add new functionality
 bloat switch or if - then code
 … remove functionality
 hunt for all parts that must be removed
 … change functionality
 hunt for all parts that must be changed

SWE 316: Software Design and Architecture


Object Orientation Classes and Objects Example Polymorphism Interfaces Things to be considered 17/24

Aspects of the Customer Design Needing


Improvement
 We need to visualize the design
 Code not an effective way to understand design

 The design’s maintainability still has flaws


 As the application grows, specialized class(es) will be required
to interact with the user

SWE 316: Software Design and Architecture


Object Orientation Classes and Objects Example Polymorphism Interfaces Things to be considered 18/24

What’s Needed to Specify Functionality


 Name of the function  Exceptions (if any)
Example: add Example: IOException

 Argument types(if any)  More(?)


Example:  Are parameters inputs
 First parameter: integer and/or outputs?
 Second parameter: float  Describe what the function
does (natural language)

 Return type
Example: double, reference
type, void

SWE 316: Software Design and Architecture


Object Orientation Classes and Objects Example Polymorphism Interfaces Things to be considered 19/24

Polymorphism
 the use of several versions of a
method, one in each derived class.

 This enables
objectOfBaseClass.theMethod() to be
interpreted variously at runtime,
depending on what derived class
objectOfBaseClass belongs to.

SWE 316: Software Design and Architecture


Object Orientation Classes and Objects Example Polymorphism Interfaces Things to be considered 20/24

The Need For Interfaces: Simplify …

class Draw
{ …
int setColor( String ) { … }
Pen getStandardPen() { … }
int getLogoStyle() { … }
void setColor( int ) { … }
void drawLogo( int, int ) { … }
void speedUpPen( int ) { … }

}

SWE 316: Software Design and Architecture


Object Orientation Classes and Objects Example Polymorphism Interfaces Things to be considered 21/24

Interface Example: a Draw Class


 Functions dealing with the pen used



Pen getStandardPen()
void speedUpPen( int )
...
}
 Functions dealing with the colors available



void setColor( int )
int setColor( String )
...
}
 Functions covering the drawing of the company’s logo



void drawLogo( int, int )
int getLogoStyle()
...

SWE 316: Software Design and Architecture


} Logo interface
Object Orientation Classes and Objects Example Polymorphism Interfaces Things to be considered 22/24

Interfaces

An interface is a set of function


prototypes (each with name, parameter
types, return type, exception type).

SWE 316: Software Design and Architecture


Object Orientation Classes and Objects Example Polymorphism Interfaces Things to be considered 23/24

Issues to be Addressed
 How do we visualize a set of classes?
 How can classes relate to each other?
 How should classes relate to each other?
 How can we describe functionality occurring among
several classes?
 How do we describe the manner in which objects
respond to events occurring on them?
 Are there patterns of class usage that recur?
 So we can existing reuse design parts
SWE 316: Software Design and Architecture
Object Orientation Classes and Objects Example Polymorphism Interfaces Things to be considered 24/24

Summary of This Chapter


 A Class represents a concept
 Example: House

 An Object is an instance of a class


 Example: 23 Main Street, Springfield

 Classes can relate in several ways: Mainly …


 A Client of a class refers to that class in one of its methods
 Inheritance: “kind of” relationship
 Aggregation:“has a” relationship, explained in chapter xx

 Polymorphism means “action depends on context”


 Executing anObject.aMethod() actually executes the version of aMethod()
in the subclass that anObject belongs to
SWE 316: Software Design and Architecture

You might also like