2

假设我有一个多维数组作为类的成员和许多方法,它们循环遍历数组的每个元素,然后对其进行操作。代码可能如下所示:

public class Baz {

    private Foo[][] fooArray = new Foo[100][100];

    public Baz() {
        for (int i = 0; i < fooArray.length; i++) {
            for (int j = 0; j < fooArray[i].length; j++) {
                // Initialize fooArray
            }
        }
    }

    public void method1() {
        for (int i = 0; i < fooArray.length; i++) {
            for (int j = 0; j < fooArray[i].length; j++) {
                // Do something with fooArray[i][j] 
            }
        }
    }

    public void method2() {
        for (int i = 0; i < fooArray.length; i++) {
            for (int j = 0; j < fooArray[i].length; j++) {
                // Do something else with fooArray[i][j] 
            }
        }
    }

    // and so on
}

现在,由于循环的代码总是相同的,只有循环内的操作发生了变化,有没有什么办法可以将循环的代码重构为一个单独的方法?能做就太好了

doInLoop(functionToExecute());

如果可能的话,做这样的事情最接近的替代品是什么?

4

3 回答 3

6

您正在寻找的是命令模式:定义一个单一方法接口并将每个用例实现为匿名类。您将将此接口的一个实例传递给一个方法,该方法执行所有样板文件并仅为有趣的部分调用您的方法:

public void forAllMembers(Foo[][] fooArray, Command c) {
    for (int i = 0; i < fooArray.length; i++) {
        for (int j = 0; j < fooArray[i].length; j++) {
            c.execute(fooArray[i][j]);
        }
    }
}

或者,等待 Java 8,它将引入 Lambda,并为您的问题提供一流的解决方案!

于 2013-07-31T14:45:14.703 回答
2

你可以这样:

public void method1(Performer p) {
    for (int i = 0; i < fooArray.length; i++) {
        for (int j = 0; j < fooArray[i].length; j++) {
            p.doIt(fooArray[i][j]);
        }
    }
}


static interface Performer {

    public void doIt(int ij);
}

然后实现不同的执行者并将它们传递给这个单一的方法。

这种方法称为命令模式

于 2013-07-31T14:44:57.750 回答
2
public Baz() {
    for (int i = 0; i < fooArray.length; i++) {
        for (int j = 0; j < fooArray[i].length; j++) {
            fooArray[i][j] = initArray(/* .. */);
            doSomethingWithFooArray(fooArray[i][j] );
            doSomethingElseWithFooArray(fooArray[i][j] );
        }
    }
}

如果你想创建一些通用的东西,你可以使用Interface

public interface FooItf{
   public void doSomethingWithFooArray(int value );
   public void doSomethingElseWithFooArray(int value );
   public int initArray(/* .. */);
 } 

现在你可以写一些东西了:

 public looping(FooItf foo) {
    for (int i = 0; i < fooArray.length; i++) {
        for (int j = 0; j < fooArray[i].length; j++) {
            fooArray[i][j] = foo.initArray(/* .. */);
            foo.doSomethingWithFooArray(fooArray[i][j] );
            foo.doSomethingElseWithFooArray(fooArray[i][j] );
        }
    }
}

FooItf现在,您可以基于任何内部逻辑生成多个类并实现它们。

于 2013-07-31T14:45:04.970 回答