我如何 Refactor/Extract 处理 java 中的这种气味代码?
How do i Refactor/Extract method on this smell codes in java?
我在重构这段代码时遇到了问题。我如何提取这个长方法?
我不知道这些代码中的气味代码在哪里,你们能帮我弄清楚这些气味代码以及如何重构这些代码吗?
private boolean placingFlag = false;
protected Scanner scan = new Scanner(System.in);
public void play() {
clear();
print();
if(placingFlag) {
System.out.println("currently your command is for placing/unplacing flag. Type 'switch' to start opening squares");
} else {
System.out.println("currently your command is for opening square. Type 'switch' to placing flag");
}
do {
System.out.print("Input coordinate to command: ");
String input = scan.nextLine().trim();
if(input.equalsIgnoreCase("switch")) {
placingFlag = !placingFlag;
break;
}
if(input.length() != 2) {
System.out.println("invalid coordinate");
continue;
}
char c1 = input.charAt(0);
char c2 = input.charAt(1);
int x = c1 - 'A';
int y = c2 - '1';
if(x < 0 || x >= gameSetting.getWidth()) {
System.out.println("invalid coordinate");
continue;
}
if(y < 0 || y >= gameSetting.getHeight()) {
System.out.println("invalid coordinate");
continue;
}
if(!placingFlag) {
if(board[y][x].flagged){
System.out.println("cannot open flagged square");
continue;
}
if(board[y][x].getType().equalsIgnoreCase("mine")) {
this.lose();
return;
}
open(x, y);
if(isWin()) {
this.win();
return;
}
} else {
if(board[y][x].getType().equalsIgnoreCase("number")) {
System.out.println("opened squared cannot be flagged");
continue;
}
board[y][x].flagged = !board[y][x].flagged;
}
break;
}while(true);
play();
}
请大佬们指点一下这些代码如何提取这些长方法:)
还不错。你可以做一件事——根据输入将阅读输入与播放分开:
private static class GameMove {
int x;
int y;
boolean switchFlagPlacingMode;
}
private GameMove readNextMove() {
// read in using the scanner
// and validate the coordinates
}
另一件事 - while(true)
绝对是一种代码味道,你拥有的 continue
、break
和 return
语句的数量也是如此 - 它们构成了代码很难追踪。考虑类似
boolean gameOver = false;
while(!gameOver) {
boolean isMoveValid = false;
GameMove nextMove = readNextMove();
while(!isMoveValid) {
// validate, set isMoveValid
// if invalid: nextMove = readNextMove();
}
// process the move
if (isWin()) {
this.win();
gameOver = true;
}
// similar for loss
}
我在重构这段代码时遇到了问题。我如何提取这个长方法? 我不知道这些代码中的气味代码在哪里,你们能帮我弄清楚这些气味代码以及如何重构这些代码吗?
private boolean placingFlag = false;
protected Scanner scan = new Scanner(System.in);
public void play() {
clear();
print();
if(placingFlag) {
System.out.println("currently your command is for placing/unplacing flag. Type 'switch' to start opening squares");
} else {
System.out.println("currently your command is for opening square. Type 'switch' to placing flag");
}
do {
System.out.print("Input coordinate to command: ");
String input = scan.nextLine().trim();
if(input.equalsIgnoreCase("switch")) {
placingFlag = !placingFlag;
break;
}
if(input.length() != 2) {
System.out.println("invalid coordinate");
continue;
}
char c1 = input.charAt(0);
char c2 = input.charAt(1);
int x = c1 - 'A';
int y = c2 - '1';
if(x < 0 || x >= gameSetting.getWidth()) {
System.out.println("invalid coordinate");
continue;
}
if(y < 0 || y >= gameSetting.getHeight()) {
System.out.println("invalid coordinate");
continue;
}
if(!placingFlag) {
if(board[y][x].flagged){
System.out.println("cannot open flagged square");
continue;
}
if(board[y][x].getType().equalsIgnoreCase("mine")) {
this.lose();
return;
}
open(x, y);
if(isWin()) {
this.win();
return;
}
} else {
if(board[y][x].getType().equalsIgnoreCase("number")) {
System.out.println("opened squared cannot be flagged");
continue;
}
board[y][x].flagged = !board[y][x].flagged;
}
break;
}while(true);
play();
}
请大佬们指点一下这些代码如何提取这些长方法:)
还不错。你可以做一件事——根据输入将阅读输入与播放分开:
private static class GameMove {
int x;
int y;
boolean switchFlagPlacingMode;
}
private GameMove readNextMove() {
// read in using the scanner
// and validate the coordinates
}
另一件事 - while(true)
绝对是一种代码味道,你拥有的 continue
、break
和 return
语句的数量也是如此 - 它们构成了代码很难追踪。考虑类似
boolean gameOver = false;
while(!gameOver) {
boolean isMoveValid = false;
GameMove nextMove = readNextMove();
while(!isMoveValid) {
// validate, set isMoveValid
// if invalid: nextMove = readNextMove();
}
// process the move
if (isWin()) {
this.win();
gameOver = true;
}
// similar for loss
}