Reputation: 3520
Let's suppose I have an interface named "Controller". Several classes implement this interface and I don't know these classes (e.g. the class names are located in an xml-file). Now for this Controller-implementing classes to work they have to get some references to other objects (maybe data objects). And this is my question, namely what is the best way to initialize such objects (the Controller ones)?
I thought of several solutions but I'm not really sure what's the best approach here.
First: When instantiating the object from the class name I could search for the "special" constructor (via reflection) which has the object references that the Controller-object needs. But from what I read in other questions this is less likely a good solution because I would force a special constructor to exist in the class. And sometimes I read that reflection in general is evil and is better avoided.
Second: I add a special init(a,b,c)-method to the Controller-interface which would need to be called directly after the object was created. This would force a sequence of calls (first init(..), then rest) to the object to make it working which is likely bad too. Btw, are init()-methods generelly a bad thing in interfaces?
Third: After reading this comment I thought about the following: Instead of having the class name of the class implementing the Controller-interface (in the xml file) I have the class name of a factory which belongs to the concrete Controller-class. And this factory would implement an interface with the method createController(a,b,c) and the factory then would know which class it would have to instantiate and also which constructor to call to carry over the other references (like data objects). Drawback of this would be the additional class just to instantiate the Controller-class and maybe a little overhead in general.
What do you think is the best way of doing this? Or can you think of something else which might be better than these three ways?
Thanks!
Upvotes: 0
Views: 928
Reputation: 533930
Another option could be to use the Unsafe.allocateInstance(Class) to create an instances without calling a constructor. You can set the fields using reflections.
This assumes that your constructors don't have any side effects.
Upvotes: 0
Reputation: 7716
What you are trying to do is very similar to what Spring does. In your xml file, your controller node would have child nodes to specify properties to be set. Your controller is instatiated by calling the default constructor. Then properties are set using reflection.
Upvotes: 2
Reputation: 43337
In something similar in another language, I've been known to use the init() solution.
Upvotes: 0
Reputation: 882851
Of the approaches you mention, I'd pick the second (factory-based one). However, since what you're doing is a form of dependency injection, also consider Guice, http://code.google.com/p/google-guice/ -- it may enable you to automate much of this work.
Upvotes: 4