Как мне сделать Refactor / Extract метод для этого кода запаха в java? - PullRequest
0 голосов
/ 21 апреля 2020

У меня была проблема с рефакторингом этого кода. как извлечь этот длинный метод? Я не знаю, где код запаха в этих кодах, можете ли вы, ребята, помочь мне разобраться в этом коде запаха и как реорганизовать этот код?

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();
    }

пожалуйста, ребята, дайте мне понимание этого кода, как чтобы извлечь эти длинные метод:)

1 Ответ

0 голосов
/ 22 апреля 2020

Это не так уж плохо. Одна вещь, которую вы могли бы сделать - отделить вход для чтения от игры на основе этого ввода:

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
}


...