Java Reflection坏模式?

时间:2010-06-24 08:53:38

标签: java design-patterns reflection

假设我有很多类似的类(本例中RTS中的单位), 即,类Unit和子类UnitAUnitBUnitC等。

所有Unit类都有以下构造函数(包括Unit)

public class UnitX {
    public UnitX(FileReader fr) {
         ...read parameters for constructing the unit...
    }
}

包含参数的文件格式为

UnitX params
UnitY params
....

并创建文件中所有单元的列表将是一个类似

的循环
Class[] params = {FileReader.class};
while(fr has more to read) {
    String unitType = fr.getString();
    Unit u = (Unit)
java.lang.reflect.Constructor constr = Class.forName(unitType).getConstructor(params);
    Unit u = (Unit)constr.newInstance(new Object[]{fr});
    list.add(u);
}

我意识到当我从文件创建对象时,我经常使用这种模式。 我的问题是,这是一个糟糕的模式吗?有更好的方法吗?

4 个答案:

答案 0 :(得分:3)

factory pattern的案例:

java.lang.reflect.Constructor constr = Class.forName(unitType).getConstructor(params);
Unit u = (Unit)constr.newInstance(new Object[]{fr});

可以改为

Unit u = UnitFactory.create( unitType, fr );

然后工厂是if / else的列表。

答案 1 :(得分:2)

代码本身很好。由于构造函数不能成为传统编码接口的一部分,因此下一个最好的方法是一致的反射接口。

但是,如果你在许多地方重复这段代码,那就不太好了。您可以尝试将其集中到某种工厂或构建器中,该工厂或构建器从文件中提供单元名称,以及为该单元定义的参数,并将其与使用通过UnitFactory提供的参数实例化单元的处理程序实现配对。 UnitFactory使用反射来实例化命名的Unit并为其提供参数。

这允许重用,并解析从实例化中读取文件,以及实例化的方法。

答案 2 :(得分:1)

我认为你的实施没问题。另一种方法:文本文件是DSL(域特定语言)的简单形式

您可以切换到更加动态的jvm兼容语言。像groovy(我最喜欢的;-)),javascript(Rhino,...),BeanShell,jython等动态语言可以更容易地用于实现特定于域的语言(DSL)。对于更复杂的DSL,您可以查看eclipse XText项目。

答案 3 :(得分:0)

这是一个简单的,减少序列化。如果符合你的目的,我会说这很好。