方法可读性更短吗?

时间:2011-05-07 15:20:10

标签: java methods refactoring

我写了这个方法:

private int maxSequence (char player , Cell c)
{
    int row = c.getRow();
    int col = c.getCol();
    int maxVert = 0;
    int maxHor = 0;
    int maxDiag = 0;

    if (player == 'O')
    { 

        for (int j = 0; j < _board[0].length; j++)
        {
            if ( (_board[col][row+j] == 'O') || (_board[col][row-j] == 'O') )
            {
                maxVert++;
            }

            if ( (_board[col+j][row] == 'O') || (_board[col-j][row] == 'O') )
            {
                maxHor++;
            }

            if ( (_board[col+j][row+j] == 'O') || (_board[col-j][row-j] == 'O') )
            {
                maxDiag++;
            }
        }
    }

    if (player == 'X')
    {
        for (int j = 0; j < _board[0].length; j++)
        {
            if ( (_board[col][row+j] == 'O') || (_board[col][row-j] == 'X') )
            {
                maxVert++;
            }

            if ( (_board[col+j][row] == 'O') || (_board[col-j][row] == 'X') )
            {
                maxHor++;
            }

            if ( (_board[col+j][row+j] == 'O') || (_board[col-j][row-j] == 'X') )
            {
                maxDiag++;
            }
        }
    }

    if ( (maxDiag >= maxVert) && (maxDiag >= maxHor) )
    {
        return maxDiag;
    }

    else if ( (maxVert >= maxDiag) && (maxVert >= maxHor) )
    {
        return maxVert;
    }

    else
    {
        return maxHor;
    }
}

我想知道是否有办法将方法改进为可读和/或更短?

6 个答案:

答案 0 :(得分:1)

使用O作为变量名是个坏主意。 O可能很容易误读或错误输入为0,反之亦然,,因为您似乎已经在几个地方完成了

在这种情况下,我认为你应该使用类似O_PLAYERO_MARKER而不是O的内容,出于上述原因,并且还要区分常量的两个不同含义你的代码。 (事实上​​,根据更大的上下文,我可能为这两种情况创建了几种enum类型。)

将开口花括号放在前一行上可以节省空间,并且(IMO)就像可读一样; e.g。

if (cond) {
   // blah
} else {
   // blah
}

if (cond) 
{
   // blah
} 
else 
{
   // blah
}

使用_前缀实例变量违反了Java命名标准。

最后,最后12行可以改写为:

return Math.max(maxHor, Math.max(maxVert, maxDiag));

答案 1 :(得分:0)

首先,你可能想要关注java coding convention,特别是关于namings(有意义的名字和没有下划线......),你也可以删除布尔评估周围的额外括号,如下所示。

此外,您可以将for循环合并为一个,因为它们正在执行类似的工作

if (board[col][row + j] == O || board[col][row - j] == O) 


        if (maxDiag >= maxVert && maxDiag >= maxHor) {
            return maxDiag;
        }else if (maxVert >= maxDiag && maxVert >= maxHor) {
            return maxVert;
        }else {
            return maxHor;
        }

答案 2 :(得分:0)

除了这不会编译(除非XO是实例变量)...

玩家'O'的代码与玩家'X'有何不同?答案是每个if语句中的第二个表达式......将其替换为变量,并将代码减半。

然而,更好的方法是根本不具备这些条件。但是,这需要考虑一下如何在电路板上的任意位置进行Tic-Tac-Toe AI。

答案 3 :(得分:0)

private int maxSequence (char player , Cell c)
{
    int row = c.getRow();
    int col = c.getCol();
    int maxVert = 0;
    int maxHor = 0;
    int maxDiag = 0;

    for (int j = 0; j < _board[0].length; j++)
    {
        if ( (_board[col][row+j] == O) || (_board[col][row-j] == player) )
        {
            maxVert++;
        }

        if ( (_board[col+j][row] == O) || (_board[col-j][row] == player) )
        {
            maxHor++;
        }

        if ( (_board[col+j][row+j] == 0) || (_board[col-j][row-j] == player) )
        {
            maxDiag++;
        }
    }

    return Math.max(maxDiag, Math.max(maxVert, maxHor));
}

答案 4 :(得分:0)

在大多数情况下,构建复杂的单行是一个坏主意。但是 - 在某些情况下,在这种情况下,您可以轻松地看到眼睛,多行中常见的内容以及不同的内容:

private int maxSequence (char player , Cell c)
    {
        int row = c.getRow();
        int col = c.getCol();
        int maxVert = 0;
        int maxHor = 0;
        int maxDiag = 0;

        if (player == O)
        {
            for (int j = 0; j < _board[0].length; j++)
            {
                if ((_board [col]  [row+j] == O) || (_board [col]  [row-j] == O))  maxVert++;
                if ((_board [col+j][row]   == O) || (_board [col-j][row]   == O))  maxHor++;
                if ((_board [col+j][row+j] == 0) || (_board [col-j][row-j] == O))  maxDiag++;
            }
        }
        if (player == X)
        {
            for (int j = 0; j < _board[0].length; j++)
            {
                if ((_board [col]  [row+j] == O) || (_board [col]  [row-j] == X))   maxVert++;
                if ((_board [col+j][row]   == O) || (_board [col-j][row]   == X))   maxHor++;
                if ((_board [col+j][row+j] == 0) || (_board [col-j][row-j] == X))   maxDiag++;
            }
        }
        if ((maxDiag >= maxVert) && (maxDiag >= maxHor))    return maxDiag;
        if ((maxVert >= maxDiag) && (maxVert >= maxHor))    return maxVert;
        return maxHor;
    }

在使用线后,我观察到在第一个块中,你测试OO,OO,OO,在第二个块中测试OX,OX,OX,我怀疑,你想测试XX,XX ,XX。

没有编译,在第二个视图中,我看到,有一个OO0,我希望有一个OOO(不是它,如上所述)。 :) - 啊,但是这个模式也用在纯O-Block中。

我喜欢追加,我喜欢Stehpen C的想法来表达max(a,b,c),前两个块应该被参数化块替换,并且整个程序的更大图片可能导致完全不同的设计,更面向对象。

结合这些建议,我们中途停在这里:

private int maxSequence (char player, Cell c)
{
    int row = c.getRow();
    int col = c.getCol();
    int maxVert = 0;
    int maxHor = 0;
    int maxDiag = 0;

    for (int j = 0; j < _board[0].length; j++)
    {
        if ((board [col]  [row+j] == player) || (board [col]  [row-j] == player))  maxVert++;
        if ((board [col+j][row]   == player) || (board [col-j][row]   == player))  maxHor++;
        if ((board [col+j][row+j] == player) || (board [col-j][row-j] == player))  maxDiag++;
    }
    return Math.max (maxHor, Math.max (maxVert, maxDiag));
}

中间,因为我们可能会做一个完全不同的设计 - 至少我会嗅到一个Board-class和一个Player-class。

答案 5 :(得分:0)

这里不是一个完整的答案,抱歉,今天早上喝咖啡和懒惰(这也就像学校的问题)。因此,我会保持高水平。

  1. 不要害怕方法,它们可以提高清晰度。您的for循环可以封装在一个名称解释正在发生的事情的方法中。
  2. 避免使用魔法值,将'X'字符替换为常量。
  3. 甚至更好地用玩家类包装char。 Player.for('x')返回一个玩家类。将循环中的行为委托给XPlayer,YPlayer类。
  4. 像其他海报一样,指出在可能的情况下使用Math.max和其他内置函数