Download presentation
Presentation is loading. Please wait.
Published byArchibald Wilson Modified over 9 years ago
1
Refactoring Self-Documenting Code and Functional Testing Topics: Beginning Program Bog Lesson One Documentation Comments Refactored Code
2
Refactoring Self-Documenting Code and Functional Testing import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.net.*; import java.applet.*; /** * A Simple TicTacToe applet. * A Tic Tac Toe applet. * A very simple, and mostly brain-dead * implementation of your favorite game! */
3
Refactoring Self-Documenting Code and Functional Testing /** * * In this game a position is represented by a white and black * bitmask. A bit is set if a position is occupied. There are * 9 squares so there are 1<<9 possible positions for each * side. An array of 1<<9 Booleans is created, it marks * all the winning positions. * * @version 1.2, 13 Oct 1995 * @author Arthur van Hoff * @modified 96/04/23 Jim Hagen : winning sounds * @modified 03/07/21 Sara Stoecklin : updated java version */
4
Refactoring Self-Documenting Code and Functional Testing public class TTTV0 extends Applet implements MouseListener { /** * White's current position. The computer is white. */ int white; /** * Black's current position. The user is black. */ int black;
5
Refactoring Self-Documenting Code and Functional Testing /** * The squares in order of importance... */ final static int moves[] = {4, 0, 2, 6, 8, 1, 3, 5, 7}; /** * The winning positions. */ static boolean won[] = new boolean[1 << 9]; static final int DONE = (1 << 9) - 1; static final int OK = 0; static final int WIN = 1; static final int LOSE = 2; static final int STALEMATE = 3;
6
Refactoring Self-Documenting Code and Functional Testing /** * Mark all positions with these bits set as winning. */ static void isWon(int pos) { for (int i = 0 ; i < DONE ; i++) { if ((i & pos) == pos) { won[i] = true; }
7
Refactoring Self-Documenting Code and Functional Testing /** * Initialize all winning positions. */ static { isWon((1 << 0) | (1 << 1) | (1 << 2)); isWon((1 << 3) | (1 << 4) | (1 << 5)); isWon((1 << 6) | (1 << 7) | (1 << 8)); isWon((1 << 0) | (1 << 3) | (1 << 6)); isWon((1 << 1) | (1 << 4) | (1 << 7)); isWon((1 << 2) | (1 << 5) | (1 << 8)); isWon((1 << 0) | (1 << 4) | (1 << 8)); isWon((1 << 2) | (1 << 4) | (1 << 6)); }
8
Refactoring Self-Documenting Code and Functional Testing /** * Compute the best move for white. * @return the square to take */ int bestMove(int white, int black) { int bestmove = -1;
9
Refactoring Self-Documenting Code and Functional Testing loop: for (int i = 0 ; i < 9 ; i++) { int mw = moves[i]; if (((white & (1 << mw)) == 0) && ((black & (1 << mw)) == 0)) { int pw = white | (1 << mw); if (won[pw]) { // white wins, take it! return mw; }
10
Refactoring Self-Documenting Code and Functional Testing loop: ……. for (int mb = 0 ; mb < 9 ; mb++) { if (((pw & (1 << mb)) == 0) && ((black & (1 << mb)) == 0)) { int pb = black | (1 << mb); if (won[pb]) { // black wins, take another continue loop; }
11
Refactoring Self-Documenting Code and Functional Testing loop: …… …….. // Neither white nor black can win in one move, this will do. if (bestmove == -1) { bestmove = mw; } if (bestmove != -1) { return bestmove; }
12
Refactoring Self-Documenting Code and Functional Testing loop: …… // No move is totally satisfactory, try the first one that is open for (int i = 0 ; i < 9 ; i++) { int mw = moves[i]; if (((white & (1 << mw)) == 0) && ((black & (1 << mw)) == 0)) { return mw; } // No more moves return -1; }
13
Refactoring Self-Documenting Code and Functional Testing /** * User move. * @return true if legal */ boolean yourMove(int m) { if ((m 8)) { return false; } if (((black | white) & (1 << m)) != 0) { return false; } black |= 1 << m; return true; }
14
Refactoring Self-Documenting Code and Functional Testing /** * Computer move. * @return true if legal */ boolean myMove() { if ((black | white) == DONE) { return false; } int best = bestMove(white, black); white |= 1 << best; return true; }
15
Refactoring Self-Documenting Code and Functional Testing /** * Figure what the status of the game is. */ int status() { if (won[white]) { return WIN; } if (won[black]) { return LOSE; } if ((black | white) == DONE) { return STALEMATE; } return OK; }
16
Refactoring Self-Documenting Code and Functional Testing /** * Who goes first in the next game? */ boolean first = true; /** * The image for white. */ Image notImage; /** * The image for black. */ Image crossImage;
17
Refactoring Self-Documenting Code and Functional Testing /** * Initialize the applet. Resize and load images. */ public void init() { notImage = getImage(getCodeBase(), "oimage.gif"); crossImage = getImage(getCodeBase(), "ximage.gif"); addMouseListener(this); } public void destroy() { removeMouseListener(this); }
18
Refactoring Self-Documenting Code and Functional Testing /** * Paint it. */ public void paint(Graphics g) { Dimension d = getSize(); g.setColor(Color.black); int xoff = d.width / 3; int yoff = d.height / 3; g.drawLine(xoff, 0, xoff, d.height); g.drawLine(2*xoff, 0, 2*xoff, d.height); g.drawLine(0, yoff, d.width, yoff); g.drawLine(0, 2*yoff, d.width, 2*yoff);
19
Refactoring Self-Documenting Code and Functional Testing int i = 0; for (int r = 0 ; r < 3 ; r++) { for (int c = 0 ; c < 3 ; c++, i++) { if ((white & (1 << i)) != 0) { g.drawImage(notImage, c*xoff + 1, r*yoff + 1, this); } else if ((black & (1 << i)) != 0) { g.drawImage(crossImage, c*xoff + 1, r*yoff + 1, this); }
20
Refactoring Self-Documenting Code and Functional Testing /** * The user has clicked in the applet. Figure out where * and see if a legal move is possible. If it is a legal * move, respond with a legal move (if possible). */ public void mouseReleased(MouseEvent e) { int x = e.getX(); int y = e.getY();
21
Refactoring Self-Documenting Code and Functional Testing switch (status()) { case WIN: case LOSE: case STALEMATE: play(getCodeBase(), "audio/return.au"); white = black = 0; if (first) { white |= 1 << (int)(Math.random() * 9); } first = !first; repaint(); return; }
22
Refactoring Self-Documenting Code and Functional Testing // Figure out the row/column Dimension d = getSize(); int c = (x * 3) / d.width; int r = (y * 3) / d.height; if (yourMove(c + r * 3)) { repaint();
23
Refactoring Self-Documenting Code and Functional Testing switch (status()) { case WIN: play(getCodeBase(), "audio/yahoo1.au"); break; case LOSE: play(getCodeBase(), "audio/yahoo2.au"); break; case STALEMATE: break;
24
Refactoring Self-Documenting Code and Functional Testing default: if (myMove()) { repaint(); switch (status()) { case WIN: play(getCodeBase(), "audio/yahoo1.au"); break; case LOSE: play(getCodeBase(), "audio/yahoo2.au"); break; case STALEMATE: break; default: play(getCodeBase(), "audio/ding.au"); }
25
Refactoring Self-Documenting Code and Functional Testing } else { play(getCodeBase(), "audio/beep.au"); } } else { play(getCodeBase(), "audio/beep.au"); }
26
Refactoring Self-Documenting Code and Functional Testing public void mousePressed(MouseEvent e) { } public void mouseClicked(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public String getAppletInfo() { return "TicTacToe by Arthur van Hoff"; }
27
Refactoring Self-Documenting Code and Functional Testing Lesson One: Self-Documenting Code and Functional Testing
28
Refactoring Self-Documenting Code and Functional Testing Process 1. Read, review and understand 2. Format and comment 3. Perform functional testing 4. Perform documenting refactorings
29
Refactoring Self-Documenting Code and Functional Testing 1. Read, review and understand A. Read existing code Not part of refactoring but necessary. B. Review it for understandability Do the variables have meaningful names? Are their enough comments Do the methods have meaningful names?
30
Refactoring Self-Documenting Code and Functional Testing 2. Format and comment A. Format the code according to supplied standards Format the code by some standard to aid in readability Comment code for understanding After reading the code add any needed comments to increase understandability
31
Refactoring Self-Documenting Code and Functional Testing import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.net.*; import java.applet.*; /** * A Simple TicTacToe applet. A Tic Tac Toe applet. * A very simple, and mostly brain-dead * implementation of your favorite game! */ My format- get rid of extra white space to show on screens
32
Refactoring Self-Documenting Code and Functional Testing /** * A bitmask is used for the two players denoting positions occupied. * Each bit represents a square on the board 0..8. * The bit is 0 if not occupied and 1 if occupied. * Winning is determined by comparing the bitmask with * an array of Booleans that marks all the winning positions. * @version 1.2, 13 Oct 1995 * @author Arthur van Hoff * @modified 96/04/23 Jim Hagen : winning sounds * @modified 03/07/21 Sara Stoecklin : updated java version */ Rewrite comments to make them clearer
33
Refactoring Self-Documenting Code and Functional Testing public class TTTV11 extends Applet implements MouseListener { static final int DONE = (1 << 9) - 1; // sentinal for square loop static final int LOSE = 2; // status for user wins static final int OK = 0; // status for game continues static final int STALEMATE = 3; // status for a tie static final int WIN = 1; // status for computer wins Place all class constants first in alphabetical order
34
Refactoring Self-Documenting Code and Functional Testing int black; // user bitmask denotes user squares occupied Image crossImage; // user image boolean first = true; // who goes first next game // The squares in order of importance... positions 0..8 final static int moves[] = {4, 0, 2, 6, 8, 1, 3, 5, 7}; Image notImage; // computer image int white; // computer bitmask denotes squares occupied static boolean won[] = new boolean[1 << 9]; // winning states Place all class variables next in alphabetical order
35
Refactoring Self-Documenting Code and Functional Testing static void isWon(int pos) { // mark winning squares as true win for (int i = 0 ; i < DONE ; i++) { if ((i & pos) == pos) { won[i] = true; } // end if (i & pos) } // end for } // end isWon I move comments to save real estate
36
Refactoring Self-Documenting Code and Functional Testing static { // initialize winning squares by shifting a one n bits isWon((1 << 0) | (1 << 1) | (1 << 2)); // row one win isWon((1 << 3) | (1 << 4) | (1 << 5)); // row two win isWon((1 << 6) | (1 << 7) | (1 << 8)); // row three win isWon((1 << 0) | (1 << 3) | (1 << 6)); // col one win isWon((1 << 1) | (1 << 4) | (1 << 7)); // col two win isWon((1 << 2) | (1 << 5) | (1 << 8)); // col three win isWon((1 << 0) | (1 << 4) | (1 << 8)); // dia right win isWon((1 << 2) | (1 << 4) | (1 << 6)); // dia left win } // end static Document all possible statements
37
Refactoring Self-Documenting Code and Functional Testing 3. Functional testing Execute the program and identify functional tests Identify some functional tests to assure that the program CONTINUES to work as you add refactorings to the code. Lack of good functional tests causes problems in subsequent refactorings so take your time on this tasks. Document Tests to assure completeness in testing. Document as complete as possible the needed tests. Create a excel spread sheet that identifies and clearly documents the needed tests.
38
Refactoring Self-Documenting Code and Functional Testing
39
Refactoring Self-Documenting Code and Functional Testing 4.Perform Refactorings 1. Rename Method 2. Rename Constants 3. Rename Variables
40
Refactoring Self-Documenting Code and Functional Testing Summary: The name of a method does not reveal its purpose Change the name of the method. Rename Method
41
Refactoring Self-Documenting Code and Functional Testing Rename Method: Motivation: Methods should be named in a way the communicates their intension. Think what the comment for the method would be and turn that comment into the name of the method.
42
Refactoring Self-Documenting Code and Functional Testing Rename Method: Customer ____________ getinvcrelmt () Customer ____________ getInvoiceCreditLimit()
43
Refactoring Self-Documenting Code and Functional Testing Rename Method: Mechanics: Check if method signature is implemented by a super or sub class. If so perform these steps for each implementation. Declare new method with new name and copy old body into new method. Change body of old so it calls the new one. Find references to old and change them to refer to new one. Remove old method. Compile and test.
44
Refactoring Self-Documenting Code and Functional Testing CONSTANTS static final int CONTINUE = 0; // OLD OK status for game continues static final int ENDINGSTATE=(1<< 9)-1; //OLD DONE 111 111 111 Change these two constants to make code clearer…… TEST BETWEEN CHANGES. Rename constants, variables methods
45
Refactoring Self-Documenting Code and Functional Testing if (won[black]) { return LOSE; } if ((black | white) == DONE) { return STALEMATE; } return OK; BECOMES if (won[black]) { return LOSE; } if ((black | white) == DONE) { return STALEMATE; } return CONTINUE; TEST BETWEEN CHANGES.
46
Refactoring Self-Documenting Code and Functional Testing VARIABLES Image crossImage; // user image Image notImage; // computer image BECOMES computerImage = getImage(getCodeBase(), "oimage.gif"); userImage = getImage(getCodeBase(), "ximage.gif"); int white; // White's current position. The computer is white. int black; Black's current position. The user is black. BECOMES int userStatus; //user bitmask denotes user squares occupied OLD BLACK int computerStatus; //computer bitmask denotes squares occupied WHITE Rename constants, variables methods
47
Refactoring Self-Documenting Code and Functional Testing if ((white & (1 << i)) != 0) { g.drawImage(notImage, c*xoff + 1, r*yoff + 1, this); } else if ((black & (1 << i)) != 0) { g.drawImage(crossImage, c*xoff + 1, r*yoff + 1, this); BECOMES if ((computerStatus & (1 << i)) != 0) { // if computer square taken g.drawImage(computerImage, c*xoff + 1, r*yoff + 1, this); } else if ((userStatus & (1 << i)) != 0) { // if user square taken g.drawImage(userImage, c*xoff + 1, r*yoff + 1, this);
48
Refactoring Self-Documenting Code and Functional Testing VARIABLES int bestMove(int white, int black) BECOMES int bestMove(int computerStatus,int userStatus) { //compute best move int pw = white | (1 << mw); BECOMES int pw = computerStatus | (1 << mw); int pb = black | (1 << mb); BECOMES int pb = userStatus | (1 << mb);
49
Refactoring Self-Documenting Code and Functional Testing white = black = 0; BECOMES computerStatus = userStatus = 0; white |= 1 << (int)(Math.random() * 9); BECOMES computerStatus |= 1 << (int)(Math.random() * 9); white |= 1 << best; BECOMES computerStatus |= 1 << best;
50
Refactoring Self-Documenting Code and Functional Testing int best = bestMove(white, black); BECOMES int best = bestMove(computerStatus, userStatus); if (((black|white)&(1<< m))!= 0) black |= 1 << m; BECOMES if (((userStatus|computerStatus)&(1<< m))!= 0) userStatus |= 1 << m; if (((white&(1<< mw))== 0) &&((black&(1<<mw))== 0)) BECOMES if (((computerStatus&(1<< mw))== 0) &&((userStatus&(1<<mw))== 0))
51
Refactoring Self-Documenting Code and Functional Testing if ((black | white) == DONE) BECOMES if ((userStatus | computerStatus) == DONE) if (won[white]) return WIN; BECOMES if (won[computerStatus]) return WIN; if (won[black]) return LOSE; BECOMES if (won[userStatus]) return LOSE; if ((black | white) == DONE) BECOMES if ((userStatus | computerStatus) == DONE)
52
Refactoring Self-Documenting Code and Functional Testing MORE VARIABLES static int moves[] = {4,0,2,6,8,1,3,5,7}; BECOMES static int mostStrategicMove[] = {4,0,2,6,8,1,3,5,7}; int mw = moves[i]; BECOMES int mw = mostStrategicMove[i]; Rename constants, variables methods
53
Refactoring Self-Documenting Code and Functional Testing won[] = new boolean[1 << 9]; BECOMES winningState[] = new boolean[1 << 9]; // winning states of game if (won[white]) BECOMES if (winningState[computerStatus]) if (won[black]) BECOMES if (winningState[userStatus]) if (won[pw]) BECOMES if (winningState[pw])
54
Refactoring Self-Documenting Code and Functional Testing METHODS boolean myMove(int m) { boolean yourMove() { BECOMES boolean legalComputerMove() { boolean legalUserMove(int m) { if (myMove()) if (yourMove(c + r * 3)) BECOMES if (legalComputerMove()) if (legalUserMove(c + r * 3)) Rename constants, variables methods
55
Refactoring Self-Documenting Code and Functional Testing OTHERS mw BECOMES int potentialComputerMove = mostStrategicMove[i]; pb BECOMES int potentialUserStatus = userStatus | (1 << j); c and r BECOMES row and col Rename constants, variables methods
56
Refactoring Self-Documenting Code and Functional Testing loop: for (int i = 0 ; i < 9 ; i++) { int mw = moves[i]; if (((white & (1 << mw)) == 0) && ((black & (1 << mw)) == 0)) { int pw = white | (1 << mw); if (won[pw]) {return mw; } // white wins, take it! for (int mb = 0 ; mb < 9 ; mb++) { if (((pw & (1 << mb)) == 0) && ((black & (1 << mb)) == 0)) { int pb = black | (1 << mb); if (won[pb]) {continue loop; } // black wins, take another } A big difference BEFORE
57
Refactoring Self-Documenting Code and Functional Testing loop: for (int i = 0 ; i < 9 ; i++) { // for square = 0 to < 9 int potentialComputerMove = mostStrategicMove[i]; if (((computerStatus & (1 << potentialComputerMove)) == 0) && ((userStatus & (1 << potentialComputerMove)) == 0)) { int potentialComputerStatus = computerStatus | (1 << potentialComputerMove); if (winningState[potentialComputerStatus]) { // computer wins return potentialComputerMove; } /// end if (not user taken ) && ( not computer taken ) A big difference AFTER
58
Refactoring Self-Documenting Code and Functional Testing // the computer did not find a winning move for (int j = 0 ; j < 9 ; j++) { // for square = 0 to < 9 if (((potentialComputerStatus & (1 << j)) == 0) && ((userStatus & (1 << j)) == 0)) { int potentialUserStatus = userStatus | (1 << j); if (winningState[potentialUserStatus]) { // user wins, take another continue loop; } // end if won } // end if && } // end for // found a move but user would win A big difference
59
Refactoring Self-Documenting Code and Functional Testing // computer has not found a winning move if (bestmove == -1) { // neither can win, this move will do bestmove = potentialComputerMove; } // end if } // end if && } // end for if (bestmove != -1) { // if no move found return the best one return bestmove; } // end if bestmove A big difference
60
Refactoring Self-Documenting Code and Functional Testing // there is no winning or good move – take mostStrategic move for (int i = 0 ; i < 9 ; i++) { // no great move, try first one open int firstAvailableComputerMove = mostStrategicMove[i]; if (((computerStatus&(1<< firstAvailableComputerMove))== 0) && (userStatus & (1 << firstAvailableComputerMove)) == 0)) { return firstAvailableComputerMove; } // end if && } // end for return -1; // return no more moves } // end best move A big difference
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.