Download - Art for Chapter 9, Specifying Interfaces
Usi
ng U
ML
, Pat
tern
s, a
nd J
ava
Ob
ject
-Ori
ente
d S
oftw
are
En
gin
eeri
ng Art for Chapter 9, Specifying
Interfaces
Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 2
Figure 9-1, the class implementor, the class extender, and the class user role.
Developer
Call Class
Class Extender
Class Implementor
Class User
Realize Class
Refine Class
Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 3
Figure 9-2, ARENA Game abstract class with user classes and extender classes.
Game
TicTacToe Chess
League
Tournament
1
*
Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 4
Figure 9-3, Declaration for the Tournament class.
public class Tournament {
private int maxNumPlayers;/* Other fields omitted */
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) {…};
/* Other methods omitted */}
Tournament
-maxNumPlayers: int
+acceptPlayer(p:Player)+removePlayer(p:Player)
+getMaxNumPlayers():int+getPlayers(): List
+isPlayerAccepted(p:Player):boolean
Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 5
Figure 9-4, Examples of invariants, preconditions, and postconditions in OCL attached as notes to the UML model.
Tournament
+acceptPlayer(p:Player)+removePlayer(p:Player)
+getMaxNumPlayers():int
-maxNumPlayers: int
+isPlayerAccepted(p:Player):boolean
«precondition»getNumPlayers() <
getMaxNumPlayers()
«precondition»!isPlayerAccepted(p)
«precondition»isPlayerAccepted(p)
«postcondition»isPlayerAccepted(p)
«postcondition»!isPlayerAccepted(p)
«invariant»getMaxNumPlayers() > 0
+getNumPlayers():int
Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 6
Tournament invariant
context Tournament inv:self.getMaxNumPlayers() > 0
Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 7
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 8
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 9
Figure 9-5, Method declarations for the Tournament class annotated with preconditions, postconditions, and invariants
public class Tournament {
/** 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;
/** Returns the current number of * players in the tournament. */
public int getNumPlayers() {…}
/** Returns the maximum number of * players in the tournament. */
public int getMaxNumPlayers() {…}
/** 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 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) {…}
}
Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 10
Figure 9-6, Associations among League, Tournament, and Player classes in ARENA.
players
* tournaments
{ordered}
Tournament
+start:Date+end:Date
+acceptPlayer(p:Player)
*League
+start:Date+end:Date
+getActivePlayers()
*Player
+name:String+email:String
* players
tournaments*
Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 11
Figure 9-7, Example situation with two Leagues, two Tournaments, and five Players.
alice:Player
bob:Player
marc:Player
winter:Tournament
tttExpert:League
joe:Player
xmas:Tournament
chessNovice:League
start=Dec 21end=Dec 22
start=Dec 23end=Dec 25
zoe:Player
Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 12
Figure 9-8, There are only three basic types of navigation. Any OCL constraint can be built using a combination of these three types.
Tournament
start:Dateend:Date
League
Player Tournament
League
1. Local attribute 2. Directly related class 3. Indirectly related class
*
*
*
*
Player
*
Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 13
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 14
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 15
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 16
Figure 9-9, Analysis objects of ARENA identified during the analysis of Announce Tournament use case.
TournamentControl
Player
players*
Tournament
name
1
1
applyForTournament()
Match
playMove()getScore()
matches*
startstatus
selectSponsors()advertizeTournament()acceptPlayer()
announceTournament()
startend
11
*
matches *
TournamentForm
*
*
acceptPlayer()removePlayer()schedule()
Advertiser
sponsors **
*
*
*
Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 17
Figure 9-10, a sequence diagram for the applyForTournament() operation.
t:Tournament:TournamentControl:Player
applyForTournament(p)
getStartDate()
getTournaments()
tournaments
p:Player
getEndDate()
isPlayerOverbooked(p)
:TournamentForm
Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 18
Figure 9-11, Adding type information to the object model of ARENA.
TournamentControl
Player
players*
Tournament
1
1
+applyForTournament()
Match
+playMove(p,m)+getScore():Map
matches*
+start:Date+status:MatchStatus
+name:String+start:Date
+end:Date
11
*
matches *
TournamentForm
*
*
+acceptPlayer(p)+removePlayer(p)+schedule()
Advertiser
sponsors **
*
*
*
+selectSponsors(advertisers):List+advertizeTournament()+acceptPlayer(p)
+announceTournament()+isPlayerOverbooked():boolean
Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 19
Pre- and post-conditions for ordering operations on TournamentControl
context TournamentControl::selectSponsors(advertisers) pre: interestedSponsors->notEmpty and
tournament.sponsors->isEmptycontext TournamentControl::selectSponsors(advertisers) post:
tournament.sponsors.equals(advertisers)
context TournamentControl::advertiseTournament() pre:tournament.sponsors->isEmpty and
not tournament.advertisedcontext TournamentControl::advertiseTournament() post:
tournament.advertised
context TournamentControl::acceptPlayer(p) pre:tournament.advertised and
interestedPlayers->includes(p) andnot isPlayerOverbooked(p)
context TournamentControl::acceptPlayer(p) post:tournament.players->includes(p)
TournamentControl
+selectSponsors(advertisers):List+advertizeTournament()+acceptPlayer(p)
+announceTournament()+isPlayerOverbooked():boolean
Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 20
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 21
Specifying invariants on Match
A match can only involve players who are accepted in the tournamentcontext Match inv:
players->forAll(p|p.tournaments->exists(t|
t.matches->includes(self)))context Match inv:
players.tournaments.matches.includes(self)
Playerplayers
*Tournament
Matchmatches
*
*tournaments
players *
Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 22
Figure 9-13, A simple example of contract inheritance: An invariant specified in a superclass must hold for all of its subclasses.
User
Player AdvertiserLeagueOwner Spectator
notify()
email:String
«invariant»email <> nil
Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 23
Figure 9-14, Embedded ODD approach. Class stubs are generated from the object design model.
RADDocumentanalysis
Analysis
Analysis model
Object design
Initial objectdesign model
Generate class stubs
Initial classstubs
ODDDocumentobject design
System design
Implementation
Commented code
Subsystemdecomposition Design goals
Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 24
Figure 9-16, new Round class and changes in the TournamentStyle, Tournament, and Round APIs.
Player
players *
name:Stringemail:String
Tournament
Match
playMove(Player,Move)getMoves():List
matches
*start
scorestatus
acceptPlayer()removePlayer()plan()
namestart
end
1
*
tournaments
players *
TournamentStyle
Round
League
*
*
notify(Player,Message)getMatches(Tournament)
1
{ordered}
plan()getPreviousRound():RoundisPlanned():booleanisCompleted():boolean
getTournamentStyle():TournamentStyle
planRounds(Tournament)
legalNumPlayers(n:int):boolean
:List
Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 25
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()) orr1.getStartDate().after(r2.getEndDate())
Bernd Bruegge & Allen H. Dutoit Object-Oriented Software Engineering: Using UML, Patterns, and Java 26
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 27
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 themcontext 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 28
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 29
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 [email protected]().isCompleted() implies
not isPlanned()