2013-07-31 7 views
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()); 

Что бы ближайшей заменой делать что-то вроде этого, если это вообще возможно?

ответ

6

Что вы ищете: Команда pattern: определить интерфейс с одним методом и реализовать его для каждого варианта использования в качестве анонимного класса. Вы передадите экземпляр этого интерфейса к способу, который делает все шаблонное и называет свой метод только для интересной части:

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, который представит лямбды и дадут вашей проблему первоклассное решение!

+0

@Skippy Я не знаком с драйверами на python, но я уверен, что этот прецедент будет покрыт генераторами и инвертией управления, который они предлагают. –

+0

@Skippy На каждом современном языке, кроме Java, функции лямбда и замыкания являются основным элементом. –

+0

@Skippy Нет, C не прекращается вообще. Случилось так, что его * область * сузилась только к низкоуровневым подпрограммам. Но он не сталкивается с какой-либо оппозицией в этой области, и это, вероятно, будет оставаться таким образом в течение по крайней мере десятилетия. –

2

Вы можете STH так:

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

затем реализовать различные исполнители и передать их в этот единственный метод.

Этот подход называется Command Pattern

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 и реализовать любую внутреннюю логику.