Transcript context

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
Bernd Bruegge & Allen Dutoit
Object-Oriented Software Engineering: Conquering Complex and Changing Systems
2
Developers play different Roles during Object
Design
Developer
Bernd Bruegge & Allen Dutoit
Class User
Call Class
Class Implementor
Realize Class
Class Extender
Refine Class
Object-Oriented Software Engineering: Conquering Complex and Changing Systems
3
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
4
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
Bernd Bruegge & Allen Dutoit
Object-Oriented Software Engineering: Conquering Complex and Changing Systems
5
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.
Bernd Bruegge & Allen Dutoit
Object-Oriented Software Engineering: Conquering Complex and Changing Systems
6
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;
public Tournament(League l, int
maxNumPlayers)
public int getMaxNumPlayers() {…};
public List getPlayers() {…};
public void acceptPlayer(Player p) {…};
public void removePlayer(Player p) {…};
public boolean isPlayerAccepted(Player p)
{…};
Bernd Bruegge & Allen Dutoit
Object-Oriented Software Engineering: Conquering Complex and Changing Systems
7
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)
Bernd Bruegge & Allen Dutoit
Object-Oriented Software Engineering: Conquering Complex and Changing Systems
8
Information Hiding Design Principles

Only the operations of a class are allowed to manipulate
its attributes
 Access attributes only via operations.

Do not apply an operation to the result of another
operation.
 Write a new operation that combines the two operations.
Bernd Bruegge & Allen Dutoit
Object-Oriented Software Engineering: Conquering Complex and Changing Systems
9
2. Add Type Signature Information
Hashtable
-numElements:int
+put()
+get()
+remove()
+containsKey()
+size()
Hashtable
Attributes and operations
without type information
are acceptable during analysis
Bernd Bruegge & Allen Dutoit
-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
10
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.
Bernd Bruegge & Allen Dutoit
Object-Oriented Software Engineering: Conquering Complex and Changing Systems
11
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
Bernd Bruegge & Allen Dutoit
Object-Oriented Software Engineering: Conquering Complex and Changing Systems
12
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)
Bernd Bruegge & Allen Dutoit
HashTable
numElements:int
put(key,entry:Object)
get(key):Object
remove(key:Object)
containsKey(key:Object):boolean
size():int
Object-Oriented Software Engineering: Conquering Complex and Changing Systems
<<postcondition>>
get(key) == entry
<<postcondition>>
!containsKey(key)
13
Contract for acceptPlayer in Tournament
(textual description of contracts, out of UML diagram)
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
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
14
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
15
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
16
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
17
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 only a combination of these three navigation types!
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
18
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
19
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
20
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
21
Specifying the Model Constraints (see Slide 20)
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
22
Specifying the Model Constraints (see Slide 20)
League
Local attribute navigation
*
context Tournament inv:
end - start <= Calendar.WEEK
+start:Date
+end:Date
+getActivePlayers()
Directly related class navigation
{ordered}
context Tournament::acceptPlayer(p) pre:
league.players->includes(p)
* tournaments
Tournament
+start:Date
+end:Date
+acceptPlayer(p:Player)
Indirectly related class navigation
* tournaments
context League::getActivePlayers post:
result = tournaments.players->asSet
players
*
La cardinalità molti potrebbe dare luogo a
ripetizioni dei valori di player per questo bisogna
convertire in Set
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
* players
Player
+name:String
+email:String
23
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
24
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 constratins 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
25
Additional Slides
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
26
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
27
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
28
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
29
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
30
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
31