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 等给出的参数。并且这些参数对于每个方法并不总是相同的。我很好地说明了这个事实,sry。我改进了给定的代码以更好地展示它。

4

3 回答 3

5

您可能想为循环体定义一个接口:

interface FieldOperation {
    void doSomeStuff(Field f);
}

然后,您可以编写一个循环方法来代替foo1foo2foo3

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 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 回答
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 回答