Chapter 8: Putting a System Together.

An Introduction to
Programming and Object
Oriented Design using Java
2nd Edition. May 2004
Jaime Niño
Frederick Hosch
Chapter 8: Putting a System Together.
Objectives
 After studying this chapter, you should understand
the following:
 phases of the software life cycle;
 iterative and compositional nature of the software life
cycle;
 functional specification of a system;
 identifying classes, their responsibilities, and relationships
among the classes, as fundamental system activities.
May 2004
NH-Chapter 8
1
Objectives
 Also, you should be able to:
 differentiate between system design and algorithm design;
 identify potential classes, their responsibilities, and
relationships, for a simple problem;
 draw a static diagram of the design of a simple system;
 implement a simple system.
May 2004
NH-Chapter 8
2
Software Life cycle
 The software life cycle involves
 analysis;
 specification;
 design;
 implementation;
 testing;
 maintenance.
May 2004
NH-Chapter 8
3
Software Life cycle
 The process is
 iterative;
 incremental;
 compositional.
May 2004
NH-Chapter 8
4
Design of a System
 Game of “simple nim”: there are two players and a
pile of sticks. Each player, in turn, removes one, two,
or three sticks from the pile. The player who removes
the last stick loses.
 Initial implementation games
“computer vs. computer.”
will
be
played
 User determines whether to play another game and
how many sticks to start with.
May 2004
NH-Chapter 8
5
Functional specification
 Basic function of the system: Play a number of
games of “simple nim,” reporting the results to the
user.
May 2004
NH-Chapter 8
6
Functional specification
 System functionality:
 Allow user to specify number of sticks at start of game.
 For each player in turn, determine what play to make
(number of sticks to remove) and make the play.
 Display state of game after each play:
number of sticks taken,
number of sticks left,
when game is over, who won.
 Allow user to choose to play another game.
May 2004
NH-Chapter 8
7
Functional specification
User interface
When the program is run, the user is offered the following menu:
Enter the number denoting the
action to perform:
Run game...............1
Exit...................2
Enter choice:
 Entering 2 terminates the program.
 Entering 1 produces the following prompt:
Enter number of sticks (a
positive integer):
May 2004
NH-Chapter 8
8
Functional specification
User interface
A play by play description of game is displayed, similar to
the following:
Player Player1 takes 1
stick(s), leaving 4.
Player Player2 takes 3
stick(s), leaving 1.
Player Player1 takes 1
stick(s), leaving 0.
Player Player2 wins.
 The original menu is again displayed.
May 2004
NH-Chapter 8
9
System design
 Need a model and user-interface components.
 No data component required.
May 2004
NH-Chapter 8
10
System design
 Identifying model objects
 Two players modeled by class Player.
 Pile of sticks modeled by class Pile
 Game, (rules of the game), modeled by class Game.
May 2004
NH-Chapter 8
11
System Design
Class: Pile
a pile of sticks for playing simple nim
Responsibilities:
Collaborators
do:
remove sticks
know:
number of sticks remaining in
the Pile
May 2004
NH-Chapter 8
12
System Design
Class: Player
a player of the simple nim game
Responsibilities:
Collaborators
Pile
do:
make a play by removing sticks
from the Pile
know:
Player’s name
the number of sticks removed on
this Player’s most recent turn
May 2004
NH-Chapter 8
13
System Design
Class: Game
a manager of a simple nim game
Responsibilities:
do:
conduct a play of game, instructing
appropriate Player to take a turn
Collaborators
Players, Pile
know:
the Players
the Pile
number of sticks that can be taken
on a turn
which Player plays next
which Player played last
when the game is over
which Player won when game is
over
May 2004
NH-Chapter 8
14
System Design
Class: NimTUI
text-based user interface for the simple nim system
Responsibilities:
Collaborators
do:
allow user to indicate whether or
not another game is to be played
allow user to specify number of
sticks to be used in a game
have a game played
display each play of a game,
when the game is over, and
which player has won
May 2004
Game
Game, Player(s)
NH-Chapter 8
15
Relationship between objects
directs
Gam e
2
Player
provides
Pile
May 2004
NH-Chapter 8
16
Case: game not over, player1
turn.
Game
Pl ayer player1
Player player 2
Pile
play
sticks
int
takeTurn
st icks
int
remove
May 2004
NH-Chapter 8
17
Pile specifications
class Pile
A pile of sticks for playing simple nim
public Pile (int sticks)
Create a new Pile, with the specified number of sticks.
require: sticks >= 0
public int sticks ()
The number of sticks remaining in this Pile.
ensure: this.sticks() >= 0
public void remove (int number)
Reduce the number of sticks by the specified amount.
require: number >= 0 and number <= this.sticks()
ensure: this.sticks() == old.sticks() - number
.
May 2004
NH-Chapter 8
18
Player specifications
class Player
A player in the game simple nim.
public Player (String name)
Create a new Player with the specified name.
ensure:
this.name().equals(name)
public String name ()
This Player’s name.
public int sticksTaken ()
Number of sticks removed on this Player's most recent turn.
Returns 0 if this Player has not yet taken a turn.
ensure:
this.sticksTaken() >= 0
.
May 2004
NH-Chapter 8
19
Game specifications
class Game
A game manager in the game simple nim.
public Game (Player player1, Player
player2,
int sticks)
Create a nim Game, with specified Players and specified number of sticks. First
Player specified (player1) plays first in game.
require:
sticks > 0
.
May 2004
NH-Chapter 8
20
Game specifications
public int sticksLeft ()
The number of sticks remaining in the pile.
ensure: this.sticksLeft() >= 0
public Player nextPlayer ()
The Player whose turn is next.
public Player previousPlayer ()
The Player who last played; returns null if no play has been made yet.
public boolean gameOver ()
The game is over.
public Player winner ()
winning Player: did not make last play in game. Returns null if game is not over.
ensure: if this.gameOver(), this.winner() !=
this.previousPlayer()
public void play ()
Conduct a play of the game, allowing the appropriate Player to take a turn. Has
no effect if the game is over.
May 2004
NH-Chapter 8
21
User interface specifications
 User ser interface is a client of the Game and the Players.
 Give user interface creation responsibility for Game, as
several games might be played.
 Give user interface creation responsibility for Players since
we might want to let user name the Players.
May 2004
NH-Chapter 8
22
User interface specifications
class NimTUI
A simple text-based user interface for the simple nim system.
public NimTUI ()
Create a new user interface.
public void start ()
Start the interface.
May 2004
NH-Chapter 8
23
Initializing class
 The initiating class will look like this:
public class NimGame {
public static void main
(String[] argv) {
(new NimTUI()).start();
}
}
May 2004
NH-Chapter 8
24
Creation responsibilities
creates
Player
creates
NimGame
NimTUI
creates
creates
Game
May 2004
NH-Chapter 8
Pile
25
Implementing class Pile
class Pile {
private int sticks;
public Pile (int sticks) {
this.sticks = sticks;
}
public int sticks () {
return sticks;
}
public void remove (int number) {
assert number <= sticks : "precondition: number <=
this.sticks()";
sticks = sticks - number;
}
public String toString () {
return "Pile: " + sticks + " sticks.";
}
}
May 2004
NH-Chapter 8
26
Test-driven implementation of
Player
 Stubbed implementation of Player.
class Player {
public Player (String name) {
}
public String name () {
return null;
}
public int sticksTaken () {
return 0;
}
public void takeTurn (Pile pile, int
maxOnATurn) {
}
NH-Chapter 8
May 2004 }
27
Test-driven implementation of
Player
Test initial state of the Player.
private void testInitialState () {
setUp();
verify(player.name().equals("Player"),
"name set initially");
verify(player.sticksTaken() == 0,
"sticksTaken initially 0");
}
private void setUp () {
May 2004
8
player = new NH-Chapter
Player("Player");
28
Test-driven implementation of Player
 To satisfy initial state test, implement queries name,
sticksTaken and constructor.
May 2004
private String name;
private int
sticksTaken;
public Player (String
name) {
this.name =
name;
this.sticksTake
n = 0;
}
public String name ()
{
return name;
}
NH-Chapter 8
public int
29
Testing method takeTurn
 Method requires two arguments, a Pile and
maxOnATurn.
 Cases to consider testing:
 maxOnATurn is smaller than number of sticks in Pile;
 maxOnATurn is equal to the number of sticks in Pile;
 maxOnATurn is larger than number of sticks in Pile.
 Test boundaries of Pile size and maxOnATurn.
May 2004
NH-Chapter 8
30
Testing method takeTurn
 we’ll test the following cases:
Pile size
5
3
2
1
5
1
May 2004
maxOnATurn
3
3
3
3
1
1
NH-Chapter 8
31
Testing method takeTurn
 Include four Piles in the test fixture:
private Player player;
private Pile pile5;
// Pile
with 5 sticks
private Pile pile3;
// Pile
with 3 sticks
private Pile pile2;
// Pile
with 2 sticks
private Pile pile1;
// Pile
with 1 stick
private void setUp () {
player = new Player("Player");
pile5 = new Pile(5);
pile3 = new Pile(3);
pile2 = new Pile(2);
NH-Chapter 8
May 2004
pile1 = new Pile(1);
32
Testing method takeTurn
/**
* Test the takeTurn method with maxOnATurn 1.
*/
private void testTakeTurnMax1 () {
player.takeTurn(pile5,1);
verify(pile5.sticks() == 4,
"takeTurn size 5, max
1");
verify(player.sticksTaken() == 1, "sticksTaken
size 5, max 1");
player.takeTurn(pile1,1);
verify(pile1.sticks() == 0,
1");
May 2004
NH-Chapter 8
"takeTurn size 1, max
33
Testing method takeTurn
/**
* Test the takeTurn method with maxOnATurn 3.
*/
private void testTakeTurnMax3 () {
player.takeTurn(pile5,3);
verify(1 <= player.sticksTaken() && player.sticksTaken() <=
3,"sticksTaken size 5, max 3");
verify(pile5.sticks() == 5 - player.sticksTaken(), "takeTurn size 5,
max 3");
player.takeTurn(pile3,3);
verify(1 <= player.sticksTaken() && player.sticksTaken() <= 3,
"sticksTaken size 3, max 3");
verify(pile3.sticks() == 3 - player.sticksTaken(), "takeTurn size 3,
max 3");
player.takeTurn(pile2,3);
verify(1 <= player.sticksTaken() && player.sticksTaken() <= 2,
"sticksTaken size 2, max 3");
verify(pile2.sticks() == 2 - player.sticksTaken(), "takeTurn size 2,
max 3");
player.takeTurn(pile1,3);
8
May 2004
verify(player.sticksTaken()
== NH-Chapter
1,"sticksTaken
size 1, max 3");
34
Testing method takeTurn
 Simplest implementation of the method : always remove one
stick from the Pile.
public void takeTurn (Pile pile, int
maxOnATurn) {
pile.remove(1);
sticksTaken = 1;
}
May 2004
NH-Chapter 8
35
Implementing class Game
 Implementation easily follows from the specs:
class Game {
private
private
private
private
private
private
May 2004
static final int MAX_ON_A_TURN = 3;
Player player1;
Player player2;
Player nextPlayer;
Player previousPlayer;
Pile pile;
NH-Chapter 8
36
Implementing class Game
public Game (Player player1, Player player2,
int sticks) {
assert
sticks
>
0
:
"precondition:
initial sticks > 0";
this.player1 = player1;
this.player2 = player2;
this.nextPlayer = player1;
this.previousPlayer = null;
this.pile = new Pile(sticks);
May 2004
}
NH-Chapter 8
37
Implementing class Game
public int sticksLeft () {
return pile.sticks();
}
public Player nextPlayer () {
return nextPlayer;
}
public Player previousPlayer () {
return previousPlayer;
}
public boolean gameOver () {
return pile.sticks() == 0;
}
public Player winner () {
if (gameOver())
return otherPlayer(previousPlayer);
else
return null;
}
May 2004
NH-Chapter 8
38
Implementing class Game
public void play () {
if (!gameOver()) {
nextPlayer.takeTurn(pile,MAX_ON_A_TURN);
previousPlayer = nextPlayer;
nextPlayer = otherPlayer(nextPlayer);
}
}
public String toString () {
return "Game with players: " + player1 + ", and
“ + player2;
}
private Player otherPlayer (Player player) {
if (player == player1)
return player2;
else
return player1;
}
of Game implementation
NH-Chapter 8
May}//end
2004
39
Implementing the TUI
 The implementation is similar to those seen in
chapter 7.
 The actual implementation is shown in the textbook
in chapter 8.
May 2004
NH-Chapter 8
40
Summary
 Put together a complete, simple system.
 Considered the life cycle of a system:
 problem analysis,
 specification,
 design,
 implementation,
 testing, and
 maintenance.
May 2004
NH-Chapter 8
41
Summary
 Lifecycle: Not a series of sequential steps.
 Process is
 iterative,
 incremental,
 compositional.
May 2004
NH-Chapter 8
42
Summary
 Designed and implemented a system to play the
simple nim game.
 System design involved
 identifying classes,
 assigning responsibilities to the classes,
 determining fundamental relationships between classes,
 writing detailed class specifications.
May 2004
NH-Chapter 8
43
Summary
 During implementation noticed that the it was quite
straightforward given the system specification.
 Implementing the Player class gave us an
opportunity to see another example of test-driven
design.
 The user interface we built was a simple, text-based
interface, similar to what we’ve seen before.
May 2004
NH-Chapter 8
44