Java 如何重构多个函数中的重复循环

Java 如何重构多个函数中的重复循环,java,loops,refactoring,duplicates,Java,Loops,Refactoring,Duplicates,我正在尝试一个TDD教程,想写好代码。我遇到了使用循环的重复代码的问题 我的代码如下所示: public Board(int rows, int columns) { this.rows = rows; this.columns = columns; blocks = new Block[rows][columns]; for (int row = 0; row < rows; row++) { for (int col = 0; c

我正在尝试一个TDD教程,想写好代码。我遇到了使用循环的重复代码的问题

我的代码如下所示:

public Board(int rows, int columns) {
    this.rows = rows;
    this.columns = columns;

    blocks = new Block[rows][columns];

    for (int row = 0; row < rows; row++) {
          for (int col = 0; col < columns; col++) {
              blocks[row][col] = new Block('.');
          }
    }
}

public boolean hasFalling(){
    boolean falling = false;

    for (int row = 0; row < rows; row++) {
        for (int col = 0; col < columns; col++) {
            if(blocks[row][col].getChar() == 'X'){
                falling = true;
            }
        }
    }

  return falling;
}

 public String toString() {
    String s = "";
    for (int row = 0; row < rows; row++) {
        for (int col = 0; col < columns; col++) {
            s += blocks[row][col].getChar();
        }
        s += "\n";
    }
    return s;
}
public void loop(Runnable runnable) {
    for (int row = 0; row < rows; row++) {
      for (int col = 0; col < columns; col++) {
          runnable.run();
      }
    }
}
公共板(int行,int列){
this.rows=行;
this.columns=列;
块=新块[行][列];
对于(int row=0;row
正如您所看到的,我在不同的方法中使用相同的for循环。有没有避免这种情况的方法?如何避免这种情况


我是用Java编程的。

我认为您对好代码的“避免代码重复”想法有点太认真了。确实,您应该避免重复代码,因为它使您的代码更难阅读和维护。但是循环是控制语句,不需要避免。它类似于
if
语句,尽管您在代码中会多次使用这些语句,但不会将if放入额外的方法中

然而,如果您确实想这样做,可以为for循环中的每个代码块创建一个Runnable,并创建如下方法:

public Board(int rows, int columns) {
    this.rows = rows;
    this.columns = columns;

    blocks = new Block[rows][columns];

    for (int row = 0; row < rows; row++) {
          for (int col = 0; col < columns; col++) {
              blocks[row][col] = new Block('.');
          }
    }
}

public boolean hasFalling(){
    boolean falling = false;

    for (int row = 0; row < rows; row++) {
        for (int col = 0; col < columns; col++) {
            if(blocks[row][col].getChar() == 'X'){
                falling = true;
            }
        }
    }

  return falling;
}

 public String toString() {
    String s = "";
    for (int row = 0; row < rows; row++) {
        for (int col = 0; col < columns; col++) {
            s += blocks[row][col].getChar();
        }
        s += "\n";
    }
    return s;
}
public void loop(Runnable runnable) {
    for (int row = 0; row < rows; row++) {
      for (int col = 0; col < columns; col++) {
          runnable.run();
      }
    }
}
public void循环(Runnable-Runnable){
对于(int row=0;row

然后可以将您想要的Runnable传递给该方法(您可能还需要以某种方式将参数传递给Runnable)。有关更多信息,请参见,例如…

我不确定如何简化所有循环(我也不完全确定您是否需要/想要),但您可以从本质上消除hasFalling()方法中的大部分代码。相反,您可以这样做:

public boolean hasFalling(){
   return toString().contains('X');
}
有两点值得注意:

如果在多个位置有完全相同的
for loop
块,则应将其分解为一个函数

此外,如果您有相同的精确循环,那么您的体系结构将很糟糕。您只需运行一次循环,并将其提供给关心它的事物—可能通过一个getter函数,该函数将该循环的结果返回给对它的任何调用

对你来说,所有这些都无关紧要。循环的
不相同。仅仅因为你有循环在这里并不重要…你用循环做什么是不同的

您确实有一个大问题,使您的代码难以理解,并可能给您带来很多困难。了解依赖注入。您的函数显然需要
才能工作,但在进一步检查函数之前,这一点并不清楚。如果函数需要(依赖于)
,则应将其传递给它


像这样重构
hasFalling(blocks)
以使事情更清楚。全球状态是一种可怕的做法,从长远来看会毁掉你。抛弃全局变量并声明依赖项。

您应该摆脱
boolean fall=false,更改<代码>下降=真
to
返回true,更改
返回下降
to
返回false。。。不是问题的答案,只是一句评论…@nhgrif这是品味的问题。我个人会像他那样做,因为我只喜欢返回语句(有些例外)到头来method@mvieghofer如果你只使用一个返回,那么至少在if语句中加一个中断,这样你就不会在你已经知道答案的情况下循环矩阵的其余部分。主要的一点是,他应该在知道他可以返回true的那一刻,就完全打破这两个
循环,并避免检查每个元素。@dkatzel是的。但是他还需要在
内部for循环
之后使用
if
语句来执行
if(falling){break;}
,以避免遍历更多的外部循环。简单地
返回true
-ing从
内部循环
更干净,我认为。这种模式看起来像是访问者模式的简化版本(但没有树)。实际上,您是在遍历过程中添加事件处理程序。我喜欢!是的,基本上是访客模式。它真的有效吗?哦,我的上帝。。在匆忙中打开Eclipse!