我目前正在设计一个通过操纵声明的字段来大量利用反射的类。因此,很多方法在它们的身体方面都有一些共同点,这有希望用这个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。我改进了给定的代码以更好地演示它。
答案 0 :(得分:5)
您可能想要为循环体定义一个接口:
interface FieldOperation {
void doSomeStuff(Field f);
}
然后您可以编写单个循环方法来代替foo1
,foo2
和foo3
:
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
}
}
}