我有以下代码。唯一的问题是我们通过checkstyle程序运行它并且它出现错误Cyclomatic Complexity是11(允许的最大值是10)。我想知道如何删除其中一个if语句以使其执行相同的操作并让程序通过测试。
/**
* Check if there is a winner on the board
* @return the winner if BLANK there is no winner
**/
public char checkWinner(){
this.winner = BLANK;
int totalTiles = GRIDSIZE*GRIDSIZE;
//Check if the game has a win
for (int i=0; i < GRIDSIZE; i++) {
if((grid[i][0] == grid[i][1]) && (grid[i][1] == grid[i][2])){
winner = grid[i][0];
return winner;
}
if((grid[0][i] == grid[1][i]) && (grid[1][i] == grid[2][i])){
winner = grid[0][i];
return winner;
}
}
if((grid[0][0] == grid[1][1]) && (grid[1][1] == grid[2][2])){
winner = grid[0][0];
return winner;
}
if((grid[0][2] == grid[1][1]) && (grid[1][1] == grid[2][0])){
winner = grid[0][2];
return winner;
}
//Check if the game is a tie
if (movesMade == totalTiles){
winner = TIE;
}
return winner;
}
答案 0 :(得分:3)
我不知道检查程序是如何工作的但是如何:
if(((grid[0][0] == grid[1][1]) && (grid[1][1] == grid[2][2])) ||
((grid[0][2] == grid[1][1]) && (grid[1][1] == grid[2][0]))) {
winner = grid[1][1];
return winner;
}
如果这确实有效,那么具有讽刺意味的是,这似乎比你的代码更不易读。
答案 1 :(得分:2)
您可以提取检查行和列的方法,并重写代码,如下所示:
public char checkWinner()
{
for (int i=0; i < GRIDSIZE; i++) {
if (checkRow(i)) return winner;
if (checkColumn(i)) return winner;
}
if (checkDiagTopLeft()) return winner;
if (checkDiagBottomLeft()) return winner;
}
易于阅读且复杂性降低。
附注:显然,winner
内容可以使用重新设计,但这不是问题的一部分,如果他们愿意,可以留给读者(和评论者)练习。
答案 2 :(得分:1)
解决方案已经在那里(结合if语句),但如果方法的代码适合单个页面,我不会让Cyclomatic Complexity指示我的编码。您希望在大型项目中实现的目标是可读性和易于理解。请记住,代码只能编写一次,但可以阅读很多次。
答案 3 :(得分:0)
第一步可以是从等值表达式中删除一些冗余。 allEqual使意图更清晰。
将胜利者分配到一个领域是很奇怪的。我在重构中删除了它。如果你真的需要这个赋值,你可以在一个调用checkWinner的单独方法中完成它。返回和分配的问题是,调用者的意外副作用。
public char checkWinner() {
// Check if the game has a win
for (int i = 0; i < GRIDSIZE; i++) {
if (allEqual(grid[i][0], grid[i][1], grid[i][2])) return grid[i][0];
if (allEqual(grid[0][i], grid[1][i], grid[2][i])) return grid[0][i];
}
if (allEqual(grid[0][0], grid[1][1], grid[2][2])) return grid[0][0];
if (allEqual(grid[0][2], grid[1][1], grid[2][0])) return grid[0][2];
// Check if the game is a tie
int totalTiles = GRIDSIZE * GRIDSIZE;
return movesMade == totalTiles ? TIE : BLACK;
}
private boolean allEqual(char... c) {
for(int i=1;i<c.length;i++) if(c[i-1] != c[i]) return false;
return true;
}
打开问题:
使用GRIDSIZE常量,您不必明确地处理所有单元格:
public char checkWinner() {
// Check if the game has a win
for (int i = 0; i < GRIDSIZE; i++) {
if (rowEqual(i)) return grid[i][0];
if (columnEqual(i)) return grid[0][i];
}
if (diagonalLeftToRightEqual()) return grid[0][0];
if (diagonalRightToLefttEqual()) return grid[0][GRIDSIZE];
// Check if the game is a tie
int totalTiles = GRIDSIZE * GRIDSIZE;
return movesMade == totalTiles ? TIE : BLACK;
}
private boolean rowEqual(int r) {
for(int i=1;i<GRIDSIZE;i++) if(grid[r][i-1] != grid[r][i]) return false;
return true;
}
private boolean diagonalLeftToRightEqual() {
for(int i=1;i<GRIDSIZE;i++) if(grid[i-1][i-1] != grid[i][i]) return false;
return true;
}
答案 4 :(得分:-1)
Cyclometric复杂度衡量代码中的路径数量。您的函数几乎完全由if
语句组成。
您可以将两个或多个if
语句与or
结合使用:
if(a)
do_something();
if(b)
do_something();
应替换为:
if(a || b)
do_something();