代码之家  ›  专栏  ›  技术社区  ›  Per Alexandersson

Java反射不良模式?

  •  2
  • Per Alexandersson  · 技术社区  · 15 年前

    假设我有很多类似的类(本例中的RTS单元)。 也就是说,班级 Unit 以及子类 UnitA , UnitB , UnitC 等。

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

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

    包含参数的文件具有

    UnitX params
    UnitY params
    ....
    

    在一个文件中创建一个所有单元的列表就像一个while循环

    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 回复  |  直到 15 年前
        1
  •  2
  •   mdma    15 年前

    代码本身很好。由于构造函数不能是传统编码接口的一部分,接下来最好的事情是一致的反射接口。

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

    这允许重用,并将读取文件与实例化以及实例化方法分离。

        2
  •  3
  •   ewernli    15 年前

    这是一个 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列表。

        3
  •  1
  •   towe75    15 年前

    我认为您的实现是可以的。另一种方法:文本文件是 DSL (特定于域的语言)

    您可以切换到更动态的、与JVM兼容的语言。像groovy(我最喜欢的;-)、javascript(Rhino,…)、Beanshell、Jython等动态语言……可以更容易地用于实现特定于域的语言(DSL)。对于更复杂的DSL,您可以查看EclipseXtext项目。

        4
  •  0
  •   krock    15 年前

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