4

私は現在、宣言されたフィールドを操作することによってリフレクションを多用するクラスを設計しています。したがって、多くのメソッドには、本体に関して共通点があります。これは、(うまくいけば)次のJavaコードで示されています。

import java.lang.reflect.Field;

public class foo {
    public void foo1(/* arguments1 */) {
        for (Field f : getClass().getDeclaredFields()) {
            // do some stuff using arguments1
        }
    }

    public void foo2(/* arguments2 */) {
        for (Field f : getClass().getDeclaredFields()) {
            // do some stuff using arguments2
        }
    }

    public void foo3(/* arguments3 */) {
        for (Field f : getClass().getDeclaredFields()) {
            // do some stuff using arguments3
        }
    }

    //and so on...
}

このクラスに最終的に含まれるメソッドの数によっては、これは設計上の欠陥と見なすことができますか?getFields()たとえばの代わりに使用したい場合はgetDeclaredFields()、出現するすべてのを置き換える必要がありgetDeclaredFields()ます。これは私には良いプログラミングの練習のようには思えません。私の場合、これはあまり現実的なシナリオではないかもしれませんが、興味を引くために、この問題に取り組むデザインパターンやコンセプトがあるかどうかを知りたいと思います。

[編集]

追加の誤解を避けるために:ループ内の操作はfoo1、foo2などによって与えられた引数に依存し、それらの引数は各メソッドで常に同じであるとは限りません。私はこの事実をうまく説明しませんでした。私はそれをよりよく示すために与えられたコードを改善しました。

4

3 に答える 3

5

ループ本体のインターフェースを定義することをお勧めします。

interface FieldOperation {
    void doSomeStuff(Field f);
}

次に、、、、および:の代わりfoo1に単一のループメソッドを記述できます。foo2foo3

public void foo(/* arguments */, FieldOperation op) {
    for (Field f : getClass().getDeclaredFields()) {
        op.doSomeStuff(f);
    }
}

FieldOperation次に、いくつかのオブジェクトをインスタンス化できます。

FieldOperation foo1Operation = new FieldOperation() {
    void doSomeStuff(Field f) {
        // do some stuff that used to be in foo1()
    }
}
// etc.

これにより、適切にスケーリングされ、アクセスするフィールドのロジックが、各フィールドで実行する操作から分離されます。

編集それぞれfoo*が異なる引数のセットを必要とする場合は、それらをクラスとしてパッケージ化することをお勧めします。

class Foo1Args { . . . }
class Foo2Args { . . . }
class Foo3Args { . . . }

次に、インターフェースをジェネリックにすることができます。

interface FieldOperation<T> {
    void doSomeStuff(Field f, T args);
}

fooそして、一般的なメソッドであると定義します。

public <T> void foo(T args, FieldOperation<T> op) {
    for (Field f : getClass().getDeclaredFields()) {
        op.doSomeStuff(f, args);
    }
}
于 2012-09-10T00:53:42.847 に答える
0

ロジックを再利用してフィールドを見つけるには、ロジックを別のメソッドまたはフィールドに外部化できます。

public class foo {
    private final Field[] fields = getClass().getDeclaredFields();

    public void foo1(/* arguments */) {
        for (Field f : fields) {
            // do some stuff
        }
    }

    public void foo2(/* arguments */) {
        for (Field f : fields) {
            // do some stuff
        }
    }

    public void foo3(/* arguments */) {
        for (Field f : fields) {
            // do some stuff
        }
    }
}
于 2012-09-10T01:04:31.713 に答える
0

他のメソッドからフィルタリングする必要がある新しいフィールドを作成する代わりに、フィールドを取得するメソッドを作成してみませんか。

public class foo {
    private Field[] getDeclaredFields() { 
        return getClass().getDeclaredFields();
    }

    public void foo1(/* arguments */) {
        for (Field f : getDeclaredFields()) {
            // do some stuff
        }
    }

    public void foo2(/* arguments */) {
        for (Field f : getDeclaredFields()) {
            // do some stuff
        }
    }

    public void foo3(/* arguments */) {
        for (Field f : getDeclaredFields()) {
            // do some stuff
        }
    }
}
于 2012-09-10T02:16:02.540 に答える