简体   繁体   中英

Java Reflection bad pattern?

Let's say I have a lot of similar classes (Units in a RTS in this example), that is, the class Unit , and the subclasses UnitA , UnitB , UnitC etc.

All Unit classes have the following constructor (including Unit)

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

My file containing the parameters have the form

UnitX params
UnitY params
....

and creating a list of all units in a file would be a while-loop like

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);
}

I realized that I use this pattern very often when I create objects from files. My question is, is this a bad pattern? Is there a better way to do this?

That a case for the factory pattern :

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

could be changed into

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

The factory is then a list of if/else though.

The code itself is fine. Since constructors cannot be part of a traditional codified interface, the next best thing is the consistent reflective interface.

However, if you are repeating this code in many places, then that's not so good. You might try to centralize that into some kind of factory or builder that provides Unit names from the file, along with the parameters defined for that unit, and pair this with a handler implementation that instantiates the unit with the parameters provided via a UnitFactory. The UnitFactory uses reflection to instantiate the named Unit and provide it with the parameters.

This allows reuse, and decouples reading the file from instantiation, and the method of instantiation.

I think your implementation is ok. Another approach: the textfile is a simple form of a DSL (Domain Specific Language)

You could switch to a more dynamic jvm compatible language. Dynamic languages like groovy (my favourite ;-) ), javascript (Rhino,...), BeanShell, jython, ... can more easily be used to implement Domain specific languages (DSL). For more complex DSL's, you could take a look at the eclipse XText project.

This is a simple, cut down serialization. I would say that this is fine if it fits your purposes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM