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