450 likes | 459 Views
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;
E N D
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. NH-Chapter 8
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. NH-Chapter 8
Software Life cycle • The software life cycle involves • analysis; • specification; • design; • implementation; • testing; • maintenance. NH-Chapter 8
Software Life cycle • The process is • iterative; • incremental; • compositional. NH-Chapter 8
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 will be played “computer vs. computer.” • User determines whether to play another game and how many sticks to start with. NH-Chapter 8
Functional specification • Basic function of the system: Play a number of games of “simple nim,” reporting the results to the user. NH-Chapter 8
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. NH-Chapter 8
Functional specification • User interface • When the program is run, the user is offered the following menu: • Entering 2 terminates the program. • Entering 1 produces the following prompt: Enter the number denoting the action to perform: Run game...............1 Exit...................2 Enter choice: Enter number of sticks (a positive integer): NH-Chapter 8
Functional specification • User interface • A play by play description of game is displayed, similar to the following: • The original menu is again displayed. 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. NH-Chapter 8
System design • Need a model and user-interface components. • No data component required. NH-Chapter 8
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. NH-Chapter 8
Responsibilities: do: remove sticks know: number of sticks remaining in the Pile Collaborators System Design Class: Pilea pile of sticks for playing simple nim NH-Chapter 8
Responsibilities: 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 Collaborators Pile System Design Class: Playera player of the simple nim game NH-Chapter 8
Responsibilities: do: conduct a play of game, instructing appropriate Player to take a turn 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 Collaborators Players, Pile System Design Class: Gamea manager of a simple nim game NH-Chapter 8
Responsibilities: 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 Collaborators Game Game, Player(s) System Design Class: NimTUItext-based user interface for the simple nim system NH-Chapter 8
Relationship between objects NH-Chapter 8
Case: game not over, player1 turn. NH-Chapter 8
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 publicint sticks () The number of sticks remaining in this Pile. ensure: this.sticks() >= 0 publicvoid 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 . NH-Chapter 8
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. publicint 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 . NH-Chapter 8
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 . NH-Chapter 8
Game specifications publicint 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. publicboolean 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() publicvoid play () Conduct a play of the game, allowing the appropriate Player to take a turn. Has no effect if the game is over. NH-Chapter 8
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. NH-Chapter 8
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. NH-Chapter 8
Initializing class • The initiating class will look like this: publicclass NimGame { publicstaticvoid main (String[] argv) { (new NimTUI()).start(); } } NH-Chapter 8
Creation responsibilities NH-Chapter 8
Implementing class Pile class Pile { privateint sticks; public Pile (int sticks) { this.sticks = sticks; } publicint sticks () { return sticks; } publicvoid remove (int number) { assert number <= sticks : "precondition: number <= this.sticks()"; sticks = sticks - number; } public String toString () { return "Pile: " + sticks + " sticks."; } } NH-Chapter 8
Test-driven implementation of Player • Stubbed implementation of Player. class Player { public Player (String name) { } public String name () { returnnull; } publicint sticksTaken () { return 0; } publicvoid takeTurn (Pile pile, int maxOnATurn) { } } NH-Chapter 8
Test-driven implementation of Player • Test initial state of the Player. privatevoid testInitialState () { setUp(); verify(player.name().equals("Player"), "name set initially"); verify(player.sticksTaken() == 0, "sticksTaken initially 0"); } privatevoid setUp () { player = new Player("Player"); } NH-Chapter 8
Test-driven implementation of Player • To satisfy initial state test, implement queries name, sticksTaken and constructor. private String name; privateint sticksTaken; public Player (String name) { this.name = name; this.sticksTaken = 0; } public String name () { return name; } publicint sticksTaken () { return sticksTaken; } NH-Chapter 8
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. NH-Chapter 8
Testing method takeTurn • we’ll test the following cases: Pile size maxOnATurn 5 3 3 3 2 3 1 3 5 1 1 1 NH-Chapter 8
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 privatevoid setUp () { player = new Player("Player"); pile5 = new Pile(5); pile3 = new Pile(3); pile2 = new Pile(2); pile1 = new Pile(1); } NH-Chapter 8
Testing method takeTurn /** * Test the takeTurn method with maxOnATurn 1. */ privatevoid 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, "takeTurn size 1, max 1"); verify(player.sticksTaken() == 1, "sticksTaken size 1, max 1"); } NH-Chapter 8
Testing method takeTurn /** * Test the takeTurn method with maxOnATurn 3. */ privatevoid 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); verify(player.sticksTaken() == 1,"sticksTaken size 1, max 3"); verify(pile1.sticks()== 0, "takeTurn size 1, max 3"); } NH-Chapter 8
Testing method takeTurn • Simplest implementation of the method : always remove one stick from the Pile. publicvoid takeTurn (Pile pile, int maxOnATurn) { pile.remove(1); sticksTaken = 1; } NH-Chapter 8
Implementing class Game • Implementation easily follows from the specs: class Game { private static final int MAX_ON_A_TURN = 3; private Player player1; private Player player2; private Player nextPlayer; private Player previousPlayer; private Pile pile; NH-Chapter 8
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); } NH-Chapter 8
Implementing class Game publicint sticksLeft () { return pile.sticks(); } public Player nextPlayer () { return nextPlayer; } public Player previousPlayer () { return previousPlayer; } publicboolean gameOver () { return pile.sticks() == 0; } public Player winner () { if (gameOver()) return otherPlayer(previousPlayer); else returnnull; } NH-Chapter 8
Implementing class Game publicvoid 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; } }//end of Game implementation NH-Chapter 8
Implementing the TUI • The implementation is similar to those seen in chapter 7. • The actual implementation is shown in the textbook in chapter 8. NH-Chapter 8
Summary • Put together a complete, simple system. • Considered the life cycle of a system: • problem analysis, • specification, • design, • implementation, • testing, and • maintenance. NH-Chapter 8
Summary • Lifecycle: Not a series of sequential steps. • Process is • iterative, • incremental, • compositional. NH-Chapter 8
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. NH-Chapter 8
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. NH-Chapter 8