设计模式以减少冗余

时间:2012-09-10 00:47:55

标签: java

我目前正在设计一个通过操纵声明的字段来大量利用反射的类。因此,很多方法在它们的身体方面都有一些共同点,这有希望用这个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。我改进了给定的代码以更好地演示它。

3 个答案:

答案 0 :(得分: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);
    }
}

答案 1 :(得分: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
        }
    }
}

答案 2 :(得分: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
        }
    }
}