Lecture for Chapter 9, Object Design: Specifying Interfaces
Download
Report
Transcript Lecture for Chapter 9, Object Design: Specifying Interfaces
Using UML, Patterns, and Java
Object-Oriented Software Engineering
Chapter 9: Object Design:
Specifying Interfaces
Object Design
Object design is the process of adding details to the
requirements analysis and making implementation
decisions
The object designer must choose among different ways
to implement the analysis model with the goal to minimize
execution time, memory and other measures of cost.
Requirements Analysis: The functional model and the
dynamic model deliver operations for the object model
Object Design: We decide on where to put these operations
in the object model
Object design serves as the basis of implementation
Modified from Bruegge & Dutoit’s originals
Object-Oriented Software Engineering: Conquering Complex and Changing Systems
2
Object Design: Closing the Gap
Problem
System
Application objects
Requir ements gap
Solution objects
Custom objects
Object design gap
Off-the-shelf components
System design gap
Modified from Bruegge & Dutoit’s originals
Machine
Object-Oriented Software Engineering: Conquering Complex and Changing Systems
3
Plan for the next Lectures
1. Reuse: Identification of existing solutions
Use of inheritance
Off-the-shelf components and additional
solution objects
Design patterns
Object
Design
lectures
2. Interface specification
Describes precisely each class interface
3. Object model restructuring
Transforms the object design model to
improve its understandability and
extensibility
Mapping
Models to Code
lecture
4. Object model optimization
Transforms the object design model to
address performance criteria such as
response time or memory utilization.
Modified from Bruegge & Dutoit’s originals
Object-Oriented Software Engineering: Conquering Complex and Changing Systems
4
Interface Specification
Motivation
How can developers communicate clearly and precisely the
details of the classes so that they can make reliable
assumptions about the classes they did not implement?
Modified from Bruegge & Dutoit’s originals
Object-Oriented Software Engineering: Conquering Complex and Changing Systems
5
Developers play different Roles during Object
Design
Developer
Modified from Bruegge & Dutoit’s originals
Class User
Call Class
Class Implementor
Realize Class
Class Extender
Refine Class
Object-Oriented Software Engineering: Conquering Complex and Changing Systems
6
Class user versus Class Extender
Developers responsible for
the implementation of League are
class users of Game
Developers responsible for
the implementation of Game are
class implementors
League
Game
1
*
Tournament
TicTacToe
Chess
The developer responsible for
the implementation of TicTacToe
is a class extender of Game
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
7
Specifying Interfaces
Requirements analysis activities
Identifying attributes and operations without
specifying their types or their parameters.
Object design: Three activities
1. Add visibility information
2. Add type signature information
3. Add contracts
Modified from Bruegge & Dutoit’s originals
Object-Oriented Software Engineering: Conquering Complex and Changing Systems
8
1. Add Visibility Information
UML defines three levels of visibility:
Private (Class implementor):
A private attribute can be accessed only by the class in
which it is defined.
A private operation can be invoked only by the class in
which it is defined.
Private attributes and operations cannot be accessed by
subclasses or other classes.
Protected (Class extender):
A protected attribute or operation can be accessed by the
class in which it is defined and on any descendent of the
class.
Public (Class user):
A public attribute or operation can be accessed by any class.
Modified from Bruegge & Dutoit’s originals
Object-Oriented Software Engineering: Conquering Complex and Changing Systems
9
Implementation of UML Visibility in Java
Tournament
- maxNumPlayers: int
+
+
+
+
+
getMaxNumPlayers():int
getPlayers(): List
acceptPlayer(p:Player)
removePlayer(p:Player)
isPlayerAccepted(p:Player):boolean
public class Tournament {
private int maxNumPlayers;
Modified from Bruegge & Dutoit’s originals
public Tournament(League l, int
maxNumPlayers)
public int getMaxNumPlayers() {…};
public List getPlayers() {…};
public void acceptPlayer(Player p)
{…};
public void removePlayer(Player p)
{…}; Object-Oriented Software Engineering: Conquering Complex and Changing Systems
10
Information Hiding Heuristics
Carefully define the public interface for classes as well as
subsystems (façade)
Always apply the “Need to know” principle.
Only if somebody needs to access the information, make it
publicly possible, but then only through well defined
channels, so you always know the access.
The fewer an operation knows
the less likely it will be affected by any changes
the easier the class can be changed
Trade-off: Information hiding vs efficiency
Accessing a private attribute might be too slow (for example
in real-time systems or games)
Modified from Bruegge & Dutoit’s originals
Object-Oriented Software Engineering: Conquering Complex and Changing Systems
11
Information Hiding Design Principles
Only the operations of a class are allowed to manipulate
its attributes
Access attributes only via operations.
Hide external objects at subsystem boundary
Define abstract class interfaces which mediate between
system and external world as well as between subsystems
Do not apply an operation to the result of another
operation.
Write a new operation that combines the two operations.
Modified from Bruegge & Dutoit’s originals
Object-Oriented Software Engineering: Conquering Complex and Changing Systems
12
2. Add Type Signature Information
Hashtable
-numElements:int
+put()
+get()
+remove()
+containsKey()
+size()
Hashtable
Attributes and operations
without type information
are acceptable during analysis
Modified from Bruegge & Dutoit’s originals
-numElements:int
+put(key:Object,entry:Object)
+get(key:Object):Object
+remove(key:Object)
+containsKey(key:Object):boolean
+size():int
Object-Oriented Software Engineering: Conquering Complex and Changing Systems
13
3. Add Contracts
Contracts on a class enable caller and callee to share the
same assumptions about the class.
Contracts include three types of constraints:
Invariant:
A predicate that is always true for all instances of a class.
Invariants are constraints associated with classes or
interfaces.
Precondition:
Preconditions are predicates associated with a specific
operation and must be true before the operation is invoked.
Preconditions are used to specify constraints that a caller
must meet before calling an operation.
Postcondition:
Postconditions are predicates associated with a specific
operation and must be true after an operation is invoked.
Postconditions are used to specify constraints that the
object must ensure after the invocation of the operation.
Modified from Bruegge & Dutoit’s originals
Object-Oriented Software Engineering: Conquering Complex and Changing Systems
14
Expressing constraints in UML Models
OCL (Object Constraint Language)
OCL allows constraints to be formally specified on single
model elements or groups of model elements
A constraint is expressed as an OCL expression returning
the value true or false. OCL is not a procedural language
(cannot constrain control flow).
OCL expressions for Hashtable operation put():
Invariant:
context Hashtable inv: numElements >= 0
Precondition:
OCL expression
Context is a class
operation put
context Hashtable::put(key, entry) pre: !containsKey(key)
Post-condition:
context Hashtable::put(key, entry) post: containsKey(key) and
get(key) = entry
Modified from Bruegge & Dutoit’s originals
Object-Oriented Software Engineering: Conquering Complex and Changing Systems
15
Expressing Constraints in UML Models
A constraint can also be depicted as a note attached to
the constrained UML element by a dependency
relationship.
<<invariant>>
numElements >= 0
<<precondition>>
!containsKey(key)
<<precondition>>
containsKey(key)
<<precondition>>
containsKey(key)
Modified from Bruegge & Dutoit’s originals
HashTable
numElements:int
put(key,entry:Object)
get(key):Object
remove(key:Object)
containsKey(key:Object):boolean
size():int
<<postcondition>>
get(key) == entry
<<postcondition>>
!containsKey(key)
Object-Oriented Software Engineering: Conquering Complex and Changing Systems
16
Contract for acceptPlayer in Tournament
context Tournament::acceptPlayer(p) pre:
not isPlayerAccepted(p)
context Tournament::acceptPlayer(p) pre:
getNumPlayers() < getMaxNumPlayers()
context Tournament::acceptPlayer(p) post:
isPlayerAccepted(p)
context Tournament::acceptPlayer(p) post:
getNumPlayers() = @pre.getNumPlayers() + 1
Value of the object or attribute
before execution of the method
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
17
Contract for removePlayer in Tournament
context Tournament::removePlayer(p) pre:
isPlayerAccepted(p)
context Tournament::removePlayer(p) post:
not isPlayerAccepted(p)
context Tournament::removePlayer(p) post:
getNumPlayers() = @pre.getNumPlayers() - 1
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
18
Real and Integer Operators
Operation
equals
not equals
less
more
less or equal
more or equal
plus
minus
multiply
divide
modulus
integer division
absolute value
maximum
minimum
round
floor
Bernd Bruegge & Allen H. Dutoit
Notation
a=b
a <> b
a<b
a >b
a <= b
a >= b
a+b
a-b
a*b
a/b
a.mod(b)
a.div(b)
a.abs
a.max(b)
a.min(b)
a.round
a.floor
Result type
Boolean
Boolean
Boolean
Boolean
Boolean
Boolean
Integer or Real
Integer or Real
Integer or Real
Real
Integer
Integer
Integer or Real
Integer or Real
Integer or Real
Integer
Integer
Object-Oriented Software Engineering: Using UML, Patterns, and Java
19
String Operators
Operation
concatenation
size
to lower case
to upper case
substring
equals
not equals
Bernd Bruegge & Allen H. Dutoit
Expression
s.concat(string)
s.size
s.toLower
s.toUpper
s.substring(int, int)
s1 = s2
s1 <> s2
Result type
String
Integer
String
String
String
Boolean
Boolean
Object-Oriented Software Engineering: Using UML, Patterns, and Java
20
Using Enumerations
Customer
gender: enum{male, female}
name: String
title: String
dateOfBirth: Date
gender = #male implies title = ‘Mr. ‘
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
21
Boolean Operators
Operation
or
and
exclusive or
negation
equals
not equals
implication
if then else
Bernd Bruegge & Allen H. Dutoit
Notation
a or b
a and b
a xor b
not a
a=b
a <> b
a implies b
if a then b1 else b2 endif
Result type
Boolean
Boolean
Boolean
Boolean
Boolean
Boolean
Boolean
type of b
Object-Oriented Software Engineering: Using UML, Patterns, and Java
22
Other Special Keywords
self
An instance of the context
result
In postconditions, it refers to the return value of the context method
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
23
JavaDoc Annotation of Tournament class
public class Tournament {
/** The maximum number of players
* is positive at all times.
* @invariant maxNumPlayers > 0
*/
private int maxNumPlayers;
/** The acceptPlayer() operation
* assumes that the specified
* player has not been accepted
* in the Tournament yet.
* @pre !isPlayerAccepted(p)
* @pre getNumPlayers()<maxNumPlayers
* @post isPlayerAccepted(p)
* @post getNumPlayers() =
*
@pre.getNumPlayers() + 1
*/
public void acceptPlayer (Player p)
{…}
/** The players List contains
* references to Players who are
* are registered with the
* Tournament. */
private List players;
/** The removePlayer() operation
* assumes that the specified player
* is currently in the Tournament.
* @pre isPlayerAccepted(p)
* @post !isPlayerAccepted(p)
* @post getNumPlayers() =
@pre.getNumPlayers() - 1
*/
public void removePlayer(Player p) {…}
/** Returns the current number of
* players in the tournament. */
public int getNumPlayers() {…}
/** Returns the maximum number of
* players in the tournament. */
public int getMaxNumPlayers() {…}
}
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
24
Constraints can involve more than one class
How do we specify constraints on
more than one class?
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
25
3 Types of Navigation through a Class Diagram
1. Local attribute
Tournament
start:Date
end:Date
2. Directly related class
3. Indirectly related class
League
League
*
*
Player
*
Tournament
*
*
Player
Any OCL constraint for any class diagram can be built
using a combination of these three navigation types
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
26
Association Navigation in OCL
Association navigation is realized using the opposite rolename.
object.rolename – the set of objects on the other side of the association
From context of League
League
tournaments
*
Tournament
*
*
Player
self.tournaments refers to the set of
objects of class Tournament associated
with this league.
From context of Tournament
self.player refers to the set of objects of
class Player associated with this
tournament
If the rolename is missing, then the name of the class with lowercase first
letter is used.
If there are multiple types of associations between two classes, then
rolenames are required.
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
27
ARENA Example: League, Tournament and Player
*
League
+start:Date
+end:Date
+getActivePlayers()
{ordered}
* tournaments
Tournament
+start:Date
+end:Date
+acceptPlayer(p:Player)
* tournaments
players
*
Bernd Bruegge & Allen H. Dutoit
* players
Player
+name:String
+email:String
Object-Oriented Software Engineering: Using UML, Patterns, and Java
28
Model Refinement with 3 additional Constraints
A Tournament’s planned duration must be under one week.
Players can be accepted in a Tournament only if they are
already registered with the corresponding League.
The number of active Players in a League are those that have
taken part in at least one Tournament of the League.
To better understand these constraints we instantiate the class
diagram for a specific group of instances
2 Leagues, 2 Tournaments and 5 Players
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
29
Instance Diagram: 2 Leagues, 2 Tournaments, and 5
Players
chessNovice:League
tttExpert:League
winter:Tournament
xmas:Tournament
start=Dec 21
end=Dec 22
start=Dec 23
end=Dec 25
alice:Player
bob:Player
marc:Player
joe:Player
zoe:Player
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
30
Specifying the Model Constraints
Local attribute navigation
context Tournament inv:
end - start <= Calendar.WEEK
*
Directly related class navigation
League
+start:Date
+end:Date
+getActivePlayers()
{ordered}
* tournaments
context
Tournament::acceptPlayer(p)
pre:
league.players->includes(p)
Tournament
+start:Date
+end:Date
+acceptPlayer(p:Player)
* tournaments
players
*
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
* players
Player
+name:String
+email:String
31
Specifying the Model Constraints
Local attribute navigation
*
context Tournament inv:
end - start <= Calendar.WEEK
context
Tournament::acceptPlayer(p)
pre:
league.players->includes(p)
Tournament
+start:Date
+end:Date
+acceptPlayer(p:Player)
* tournaments
Indirectly related class navigation
result = tournaments.players->asSet
players
*
Bernd Bruegge & Allen H. Dutoit
+start:Date
+end:Date
+getActivePlayers()
{ordered}
* tournaments
Directly related class navigation
context League::getActivePlayers post:
League
Object-Oriented Software Engineering: Using UML, Patterns, and Java
* players
Player
+name:String
+email:String
32
OCL Collections
Sets
Used when navigating a single association
Sequences
Used when navigating a single ordered association
Bags
Unlike sets, bags can contain the same object multiple times
Used to accumulate objects when accessing indirectly related
objects
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
33
Operations on Collections
Operation
size
count(object)
includes(object)
includesAll(collection)
isEmpty
notEmpty
iterate(expression)
sum(collection)
exists(expression)
forAll(expression)
Bernd Bruegge & Allen H. Dutoit
Description
The number of elements in the collection
The number of occurences of object in the collection.
True if the object is an element of the collection.
True if all elements of the parameter collection are present
in the current collection.
True if the collection contains no elements.
True if the collection contains one or more elements.
Expression is evaluated for every element in the collection.
The addition of all elements in the collection.
True if expression is true for at least one element in the
collection.
True if expression is true for all elements.
Object-Oriented Software Engineering: Using UML, Patterns, and Java
34
Collection hierarchy
Collection
Set
Bag
minus
symmetricDifference
asSequence
asBag
asSequence
asSet
Bernd Bruegge & Allen H. Dutoit
Sequence
first
last
at(int)
append
prepend
asBag
asSet
Object-Oriented Software Engineering: Using UML, Patterns, and Java
35
OCL supports Quantification
OCL forall quantifier
/* All Matches in a Tournament occur within the
Tournament’s time frame */
context Tournament inv:
matches->forAll(m:Match |
m.start.after(t.start) and m.end.before(t.end))
OCL exists quantifier
/* Each Tournament conducts at least one Match on the
first day of the Tournament */
context Tournament inv:
matches->exists(m:Match | m.start.equals(start))
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
36
Summary
There are three different roles for developers during object
design
Class user, class implementor and class extender
During object design - and only during object design - we
specify visibility rules
Constraints are boolean expressions on model elements
Contracts are constraints on a class enable class users,
implementors and extenders to share the same assumption
about the class (“Design by contract”)
OCL is a language that allows us to express constraints on
UML models
Complicated constraints involving more than one class,
attribute or operation can be expressed with 3 basic navigation
types.
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
37
Additional Slides
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
38
ARENA’s object model identified during the analysis
TournamentForm
applyForTournament()
1
1
TournamentControl
* selectSponsors()
advertizeTournament()
acceptPlayer()
announceTournament()
1
*
1
Tournament
* * players
Player
*
matches *
Match
start
status
name
* start
end
acceptPlayer()
removePlayer()
schedule()
*
sponsors * *
Advertiser
matches
*
playMove()
getScore()
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
39
Adding type information to ARENA’s object model
TournamentForm
1
1
+applyForTournament()
*
TournamentControl
*
+selectSponsors(advertisers):List
+advertizeTournament()
+acceptPlayer(p)
+announceTournament()
+isPlayerOverbooked():boolean
1
1
Tournament
* *
players
Player
*
matches *
Match
+start:Date
+status:MatchStatus
+name:String
* +start:Date
+end:Date
+acceptPlayer(p)
+removePlayer(p)
+schedule()
*
sponsors * *
Advertiser
matches
*
+playMove(p,m)
+getScore():Map
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
40
Pre- and post-conditions for
ordering operations on
TournamentControl
TournamentControl
+selectSponsors(advertisers):List
+advertizeTournament()
+acceptPlayer(p)
+announceTournament()
+isPlayerOverbooked():boolean
context TournamentControl::selectSponsors(advertisers) pre:
interestedSponsors->notEmpty and
tournament.sponsors->isEmpty
context TournamentControl::selectSponsors(advertisers) post:
tournament.sponsors.equals(advertisers)
context TournamentControl::advertiseTournament() pre:
tournament.sponsors->isEmpty and
not tournament.advertised
context TournamentControl::advertiseTournament() post:
tournament.advertised
context TournamentControl::acceptPlayer(p) pre:
tournament.advertised and
interestedPlayers->includes(p) and
not isPlayerOverbooked(p)
context TournamentControl::acceptPlayer(p) post:
tournament.players->includes(p)
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
41
Specifying invariants on Tournament and
Tournament Control
All Matches of in a Tournament must occur within the time
frame of the Tournament
context Tournament inv:
matches->forAll(m|
m.start.after(start) and m.start.before(end))
No Player can take part in two or more Tournaments that
overlap
context TournamentControl inv:
tournament.players->forAll(p|
p.tournaments->forAll(t|
t <> tournament implies
not t.overlap(tournament)))
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
42
Specifying invariants on Match
Player
players *
Match
players
*
*
tournaments
Tournament
matches
*
A match can only involve players who are accepted in the tournament
context Match inv:
players->forAll(p|
p.tournaments->exists(t|
t.matches->includes(self)))
context Match inv:
players.tournaments.matches.includes(self)
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
43