Figure 9-1, the class implementor, the class extender, Call Class Class User

advertisement
Figure 9-1, the class implementor, the class extender,
and the class user role.
Developer
Bernd Bruegge & Allen H. Dutoit
Class User
Call Class
Class Implementor
Realize Class
Class Extender
Refine Class
Object-Oriented Software Engineering: Using UML, Patterns, and Java
1
Figure 9-2, ARENA Game abstract class with user
classes and extender classes.
League
Game
1
*
Tournament
Bernd Bruegge & Allen H. Dutoit
TicTacToe
Object-Oriented Software Engineering: Using UML, Patterns, and Java
Chess
2
Figure 9-3, Declaration for the Tournament class.
Tournament
-maxNumPlayers: int
public class Tournament {
private int maxNumPlayers;
/* Other fields omitted */
public
public
public
public
public
public
+getMaxNumPlayers():int
+getPlayers(): List
+acceptPlayer(p:Player)
+removePlayer(p:Player)
+isPlayerAccepted(p:Player):boolean
Tournament(League l, int maxNumPlayers)
int getMaxNumPlayers() {…};
List getPlayers() {…};
void acceptPlayer(Player p) {…};
void removePlayer(Player p) {…};
boolean isPlayerAccepted(Player p) {…};
/* Other methods omitted */
}
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
3
Figure 9-4, Examples of invariants, preconditions,
and postconditions in OCL attached as notes to the
UML model.
«invariant»
getMaxNumPlayers() > 0
«precondition»
getNumPlayers() <
getMaxNumPlayers()
Tournament
«precondition»
!isPlayerAccepted(p)
«precondition»
isPlayerAccepted(p)
Bernd Bruegge & Allen H. Dutoit
-maxNumPlayers: int
+getNumPlayers():int
+getMaxNumPlayers():int
+acceptPlayer(p:Player)
+removePlayer(p:Player)
+isPlayerAccepted(p:Player):boolean
Object-Oriented Software Engineering: Using UML, Patterns, and Java
«postcondition»
isPlayerAccepted(p)
«postcondition»
!isPlayerAccepted(p)
4
Tournament invariant
context Tournament inv:
self.getMaxNumPlayers() > 0
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
5
Tournament.acceptPlayer contract
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
6
Tournament.removePlayer contract
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
7
Figure 9-5, Method declarations for the Tournament
class annotated with preconditions, postconditions,
and invariants
public class Tournament {
/** 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 maximum number of players
* is positive at all times.
* @invariant maxNumPlayers > 0
*/
private int maxNumPlayers;
/** 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
8
Figure 9-6, Associations among League, Tournament,
and Player classes in ARENA.
*
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
9
Figure 9-7, Example situation with two Leagues, two
Tournaments, and five Players.
tttExpert:League
chessNovice: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
10
Figure 9-8, There are only three basic types of
navigation. Any OCL constraint can be built using a
combination of these three types.
1. Local attribute
Tournament
start:Date
end:Date
2. Directly related class
League
3. Indirectly related class
League
*
*
Player
*
Tournament
*
*
Player
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
11
Examples of constraints using each type of navigation
1. Local attribute
context Tournament inv:
end - start <= Calendar.WEEK
2. Directly related class
context Tournament::acceptPlayer(p) pre:
league.players->includes(p)
3. Indirectly related class
context League::getActivePlayers post:
result = tournaments.players->asSet
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
12
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))
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
13
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
14
Figure 9-9, Analysis objects of ARENA identified
during the analysis of Announce Tournament use
case.
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
15
Figure 9-10, a sequence diagram for the
applyForTournament() operation.
:Player
:TournamentForm
:TournamentControl
t:Tournament
p:Player
applyForTournament(p)
isPlayerOverbooked(p)
getStartDate()
getEndDate()
getTournaments()
tournaments
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
16
Figure 9-11, Adding type information to the object
model of ARENA.
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
17
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
18
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
19
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
20
Figure 9-13, A simple example of contract
inheritance: An invariant specified in a superclass
must hold for all of its subclasses.
User
email:String
«invariant»
email <> nil
notify()
LeagueOwner
Bernd Bruegge & Allen H. Dutoit
Player
Advertiser
Object-Oriented Software Engineering: Using UML, Patterns, and Java
Spectator
21
Figure 9-14, Embedded ODD approach. Class stubs
are generated from the object design model.
Analysis
Document
analysis
Analysis model
RAD
System design
Subsystem
decomposition
Design goals
Object design
Initial object
design model
Generate class stubs
Initial class
stubs
Implementation
Commented code
Bernd Bruegge & Allen H. Dutoit
Document
object design
ODD
Object-Oriented Software Engineering: Using UML, Patterns, and Java
22
Figure 9-16, new Round class and changes in the
TournamentStyle, Tournament, and Round APIs.
League
1
*
planRounds(Tournament)
:List
legalNumPlayers(n:int)
:boolean
getTournamentStyle()
:TournamentStyle
*
players *
TournamentStyle
tournaments
Player
name:String
email:String
notify(Player,Message)
getMatches(Tournament)
Tournament
name
start
end
acceptPlayer()
removePlayer()
plan()
{ordered}
players *
Match
start
status
score
playMove(Player,Move)
getMoves():List
Bernd Bruegge & Allen H. Dutoit
matches
*
1
*
Round
plan()
getPreviousRound():Round
isPlanned():boolean
isCompleted():boolean
Object-Oriented Software Engineering: Using UML, Patterns, and Java
23
Constraints on TournamentStyle

Only tournaments without rounds and with the right number of
players can be planned.
context TournamentStyle::planRounds(t:Tournament) pre:
t <> nil and t.rounds = nil and
legalNumPlayers(t)->contains(t.players->size)

All players are assigned to at least one match
context TournamentStyle::planRounds(t:Tournament) post:
t.getPlayers()->forAll(p|
p.getMatches(tournament)->notEmpty)
context TournamentStyle::planRounds(t:Tournament) post:
result->forAll(r1,r2| r1<>r2 implies
r1.getEndDate().before(r2.getStartDate()) or
r1.getStartDate().after(r2.getEndDate())
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
24
Invariant on Round

A player cannot be assigned to more than one match per round
context Round inv:
matches->forAll(m1:Match|
m1.players->forAll(p:Player|
p.matches->forAll(m2:Match|
m1 <> m2 implies m1.round <> m2.round)))
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
25
Constraints on Round.plan()

Invoking plan() on a Round whose previous Round is
completed results in a planned Round
context Round.plan() post:
@pre.getPreviousRound().isCompleted() implies
isPlanned()
 A round is planned if all matches have players assigned to them
context Round.isPlanned() post:
result implies matches->forAll(m|
m.players->size =
tournament.league.game.numPlayersPerMatch)
 A round is completed if all of its matches are completed.
context Round.isCompleted() post:
result implies matches->forAll(m| m.winner <> nil)
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
26
Constraints on KnockOutStyle

The number of players should be a power of two.
context KnockOutStyle::legalNumPlayers(t:Tournament) post:
result Sequence[2..t.maxNumPlayers]->select(elem|
floor(log(elem)/log(2)) = (log(elem)/log(2)))

The number of matches in a round is 1 for the last round. Otherwise, the
number of matches in a round is exactly twice the number of matches in the
subsequent round.
context KnockOutStyle::planRounds(t:Tournament) post:
result->forAll(index:Integer|
if (index = result->size) then
result->at(index).matches->size = 1
else
result->at(index).matches->size =
(2*result->at(index+1).matches->size))
endif)
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
27
Constraints on KnockOutRound

A player can play in a round only if it is the first round or if it is
the winner of a previous round.
context KnockOutRound inv:
previousRound = nil or
matches.players->forAll(p|
round.previousRound.matches->exists(m|
m.winner = p))

If the previous round is not completed, this round cannot be
planned.
context KockOutRound::plan() post:
not self@pre.getPreviousRound().isCompleted() implies
not isPlanned()
Bernd Bruegge & Allen H. Dutoit
Object-Oriented Software Engineering: Using UML, Patterns, and Java
28
Download