Am I abusing/misusing Java reflection? - java

I'm writing a program to read data from a file, which may be in one of several format (different versions of the same format, actually) and I'm using reflection for calling the appropriate function for each format. Assuming that file format is a number specified on the first byte of the file:
Class DataFile extends Model {
...
Blob file
...
public void parse() throws Exception{
InputStream is = file.get();
Class c = Class.forName("models.DataFile");
Method m = c.getMethod("parse_v"+is.read(), (Class []) null);
m.invoke(this, (Object []) null);
}
public void parse_v0() throws Exception{
...
}
public void parse_v1() throws Exception{
...
}
}
My question is, am I abusing/misusing reflection? I have the feeling that I should be using inheritance and create a different class for each file type with its own "parse" procedure, but I don't know the file type until I start parsing... and then I cannot "downcast" and just use something like ((DataFile_v1) this).parse() so I am a little lost.
Thank you for your time!

There's nothing fundamentally wrong with this, but a more flexible and extensible way to do the same thing would be to use the version information as a key in a Map, and have the values in the Map be handler objects. Then any code can register a handler (the handlers can all implement a common interface) and your reader code can just look up the handler in the Map and invoke it.
Be sure to handle the case where the Map doesn't include a handler for a particular version!

If you make a DataFile interface define a parse method, and implement the interface with multiple classes (DataFile_v1, etc.), then the calling code doesn't have to know which implementation was chosen.
DataFile dataFile = dataFileFactory.getForVersion(is.read());
dataFile.parse(file);
I'd argue that this is a better approach from a general design perspective. However, at some point you will need to create some kind of mapping between the version number and the DataFile implementations. (In this case I'm doing it in an imaginary dataFileFactory.) You'll have to determine whether it would be more appropriate to select an implementation using reflection or some other method.

I think it's OK to use reflection here. The alternative would be using inheritance or an enum (i.e. the Strategy pattern), and a map from the version code to the proper Strategy. Once you have initialized all the desired mappings, you just get the right parser object from the map and invoke it. However, setting up this solution still requires a significant amount of boilerplate code, which diminishes its readability.

What you're doing isn't bad. If you want to have the different parsers in different classes, you can't downcast as you say, but you could instantiate a new parser object. So your existing class would be a facade in front of the actual parsers which aren't instantiated until you know which format you're parsing.

You can use a collection, but using reflections is looking up a collection as well. Provided your mapping doesn't change I would use reflections.
getClass().getMethod("parse_v"+is.read()).invoke(this);

Related

Extending functionality of Strategy pattern

I am developing an app that compares files. I decided to use the Strategy design pattern, to handle different formats, so I have something like this:
public class Report {
CompareStrategy strategy;
...
}
public interface CompareStrategy {
int compare(InputStream A, InputStreamB);
}
Then, naturally I implement the compare method for different file formats.
Now suppose I wanted to add another method, that deals with certain restrictions for the comparison (e.g. omit a row in case of an Excel or csv file, or omit a node in XML).
Would it be better to:
Add another method to the interface and every implementation (there are few for the moment)
Write a new interface which inherits from CompareStrategy and then implement it?
The second question is: since the differences can be of various types - would it be OK to make a marker interface Difference to enable something like:
int compareWithDifferences(..., Iterable<Difference> differences);
and then go on defining what a difference means for the specific file format?
Now suppose I wanted to add another method, that deals with certain restrictions for the comparison (e.g. omit a row in case of an Excel or csv file, or omit a node in XML).
Looks like you need the Template Pattern
You can create some abstract class like
public abstract class XMLCompareStrategy implements CompareStrategy {
public int compare(InputStream A, InputStreamB) {
// several steps
customMethod(...);
// more steps
}
protected abstract ... customMethod(...);
}
This way you can create several classes that have the main or core functionality and provide custom details for every situation
The answer really depends on your needs:
If the method will always be implemented - add it to the existing interface. If it's only optional - create a new interface that will extend the current one, and then the implemented class could implement either the base interface or the child interface if it needs both methods.
For your second question - looks a bit like over-designing to me, but again depends on your needs.
I think you should maybe write another interface that inherit from the CompareStrategy. Like that if you need to compareWithDifferences() you can, but you don't have to use this interface you still can use the simpler one with no differences.
As Jonathan said, if you can foresee difficulties prepare for it. In that case I think you should prepare. Indeed that won't cost you much time to create another interface and you won't have to refactor later.

Using wrapper classes - java

I described my previous problem here:
Java - how can I loop methods with same name but different parameters
And I have question related to that.
Is given there example - a good example of using wrapper class?
class Wrapper{
Part param1;
File param2;
File param3;
}
class Validator{
void validate (Wrapper wrapper);
}
class ValidatorA extends Validate{
void validate (Wrapper wrapper){
//use wrapper.part...
}
}
class ValidatorC extends Validate{
void validate (Wrapper wrapper){
//use wrapper.file...
}
}
But it makes me wonder. Is wrapper correct name for it? Is is valid wrapper class? From what I read wrapper classes are used for primitives to use them as objects, shouldn't then it be named different? Or am I wrong?
I need it to be called same way, so I can loop over it so overloading is not the answer. Given class works fine - I just think if is it correct way to use wrapper name?
Wrapper is not good choice in this case. Usually wrapper is used to wrap some different things so they look alike even they are totally different. For example you may have some stream of data which comes from different sources - file, http connection, resources. All what you care is to read data from this source. So, you write wrapper which reads from any source and just deliver data.
Wrapper should not be mixed with common functionality. In example above all 3 sources could be treated as stream so natural solution would be use them all as streams. But even eventually inside wrapper they are used as streams they still require different treatment and actions to work with them. And wrapper takes care about it. You do not care what is wrapped wraps - you just use this wrapped thing in common way which wrapper provides.
In your example we have regular object which encapsulates some data and functionality. This is regular OOP approach. Calling it Wrapper only misguide users who may use this code later.

Framework to populate common field in unrelated classes

I'm attempting to write a framework to handle an interface with an external library and its API. As part of that, I need to populate a header field that exists with the same name and type in each of many (70ish) possible message classes. Unfortunately, instead of having each message class derive from a common base class that would contain the header field, each one is entirely separate.
As as toy example:
public class A
{
public Header header;
public Integer aData;
}
public class B
{
public Header header;
public Long bData;
}
If they had designed them sanely where A and B derived from some base class containing the header, I could just do:
public boolean sendMessage(BaseType b)
{
b.header = populateHeader();
stuffNecessaryToSendMessage();
}
But as it stands, Object is the only common class. The various options I've thought of would be:
A separate method for each type. This would work, and be fast, but the code duplication would be depressingly wasteful.
I could subclass each of the types and have them implement a common Interface. While this would work, creating 70+ subclasses and then modifying the code to use them instead of the original messaging classes is a bridge too far.
Reflection. Workable, but I'd expect it to be too slow (performance is a concern here)
Given these, the separate method for each seems like my best bet, but I'd love to have a better option.
I'd suggest you the following. Create a set of interfaces you'd like to have. For example
public interface HeaderHolder {
public void setHeader(Header header);
public Header getHeader();
}
I'd like your classes to implement them, i.e you's like that your class B is defined as
class B implements HeaderHolder {...}
Unfortunately it is not. Now problem!
Create facade:
public class InterfaceWrapper {
public <T> T wrap(Object obj, Class<T> api) {...}
}
You can implement it at this phase using dynamic proxy. Yes, dynamic proxy uses reflection, but forget about this right now.
Once you are done you can use your InterfaceWrapper as following:
B b = new B();
new IntefaceWrapper().wrap(b, HeaderHolder.class).setHeader("my header");
As you can see now you can set headers to any class you want (if it has appropriate property). Once you are done you can check your performance. If and only if usage of reflection in dynamic proxy is a bottleneck change the implementation to code generation (e.g. based on custom annotation, package name etc). There are a lot of tools that can help you to do this or alternatively you can implement such logic yourself. The point is that you can always change implementation of IntefaceWrapper without changing other code.
But avoid premature optimization. Reflection works very efficiently these days. Sun/Oracle worked hard to achieve this. They for example create classes on the fly and cache them to make reflection faster. So probably taking in consideration the full flow the reflective call does not take too much time.
How about dynamically generating those 70+ subclasses in the build time of your project ? That way you won't need to maintain 70+ source files while keeping the benefits of the approach from your second bullet.
The only library I know of that can do this Dozer. It does use reflection, but the good news is that it'll be easier to test if it's slow than to write your own reflection code to discover that it's slow.
By default, dozer will call the same getter/setters on two objects even if they are completely different. You can configure it in much more complex ways though. For example, you can also tell it to access the fields directly. You can give it a custom converter to convert a Map to a List, things like that.
You can just take one populated instance, or perhaps even your own BaseType and say, dozer.map(baseType, SubType.class);

Need a way to define input arguments for constructor in interface

First of all, I know it isn't possible to define constructors in interfaces in Java. But somehow, I've run into a problem where I need something very similar. Maybe there is an easy solution for my case...
I have an interface:
public interface SomeObject {
/**
* Generate a xml representation of the object.
*/
public String generateXMLRepresentation();
}
This xml-representation of the object will be stored somewhere and later on it should be possible to construct a copy of the object using this xml-representation. My intial thought was to define a constructor which takes a String as input and let every implementation of SomeObject know how to handle it and how to construct the corresponding object.
How can I achieve this?
Edit: Either I wasn't clear enough about that or I think about it the wrong way but I think that Factory or Builder patterns won't work. I need something stronger where everyone can write a new implementation of SomeObject and is forced to implement an constructor which takes an xml string. To put it another way, I do not how many or which implementations of SomeObject exist and still, I'm relying on that every implementation knows how to construct itself from an xml-representation.
I believe for this you should use the Factory pattern, since we are talking about building up an object based on a string.
So you should have different static methods constructing different implementations for a given String.
public class ObjV1 implements SomeObject(){ // objects would simply extend interface
...
}
public class SomeObjectFactory{// factory would provide construction methods for different implementations of the interface
//Hide factory constructor, so we use it only as a singleton
private SomeObjectFactory(){
}
public static ObjV1 buildV1(String str){
ObjV1 obj = new ObjV1(); // note that we're using the noarg constructor
...
return obj;
}
}
If you want to have more control over the building process, you should give the Builder pattern a try
Some Design Patterns can help you to define a solution that can handle your current context. Both the Abstract Factory and the Builder pattern can help you.
I'd rather go with the Builder design pattern. You'll end up being able to construct from simple to complex objects based solely on that XML representation you have by implementing the proper logic.
I think you should consider separating the concern of xml serialisation from whatever concern your object is dealing with. Is knowledge of to and from xml really intrinsic to the domain of your class, or is it an orthogonal concern?
Have a look at http://x-stream.github.io/
If you do not want to use xstream itself, because you can't depend on the jar, or your xml form is particular to your project, at least look at what xstream does. You should be able to define a single strategy to (reflectively?) recurse an object structure and write out xml in the form you require, and a companion class to do the opposite.

Manual object serialization in Java

I have a custom INIFile class that I've written that read/write INI files containing fields under a header. I have several classes that I want to serialize using this class, but I'm kind of confused as to the best way to go about doing it. I've considered two possible approaches.
Method 1: Define an Interface like ObjectPersistent enforcing two methods like so:
public interface ObjectPersistent
{
public void save(INIFile ini);
public void load(INIFile ini);
}
Each class would then be responsible for using the INIFile class to output all properties out to the file.
Method 2: Expose all properties of the classes needing serialization via getters/setters so that saving can be handling in one centralized place like so:
public void savePlayer(Player p)
{
INIFile i = new INIFile(p.getName() + ".ini");
i.put("general", "name", p.getName());
i.put("stats", "str", p.getSTR());
// and so on
}
The best part of method 1 is that not all properties need to be exposed, so encapsulation is held firm. What's bad about method 1 is that saving isn't technically something that the player would "do". It also ties me down to flat files via the ini object passed into the method, so switching to a relational database later on would be a huge pain.
The best part of method 2 is that all I/O is centralized into one location, and the actual saving process is completely hidden from you. It could be saving to a flat file or database. What's bad about method 2 is that I have to completely expose the classes internal members so that the centralized serializer can get all the data from the class.
I want to keep this as simple as possible. I prefer to do this manually without use of a framework. I'm also definitely not interested in using the built in serialization provided in Java. Is there something I'm missing here? Any suggestions on what pattern would be best suited for this, I would be grateful. Thanks.
Since you don't want (for some reason) to use Java serialization, you can use XML serialization. The simplest way is via XStream:
XStream is a simple library to serialize objects to XML and back again.
If you are really sure you don't want to use any serialization framework, you can of course use reflection. Important points there are:
getClass().getDeclaredFields() returns all fields of the class - both public and private
field.setAccessible(true) - makes a private (or protected) field accessible via reflection
Modifier.isTransient(field.getModifiers()) tells you whether the field has been marked with the transient keyword - i.e. not eligible for serialization.
nested object structures may be represented by a dot notation - team.coach.name, for example.
All serialization libraries are using reflection (or introspection) to achieve their goals.
I would choose Method 1.
It might not be the most object oriented way, but in my experience it is simpler, less error-prone and easier to maintain than Method 2.
If you are conserned about providing multiple implementations for your own serialization, you can use interfaces for save and load methods.
public interface ObjectSerializer
{
public void writeInt(String key, int value);
...
}
public interface ObjectPersistent
{
public void save(ObjectSerializer serializer);
public void load(ObjectDeserializer deserializer);
}
You can improve these ObjectSerializer/Deserializer interfaces to have enough methods and parameters to cover both flat file and database cases.
This is a job for the Visitor pattern.

Categories

Resources