I have an interface called Cell
. In the start of the code, I read input data from which I can come to know the implementing class (not as a class object but I can know for example the string). And after that I need to call the constructor for the implementing class to initialize an object.
What would be the best way to implement that. The first thing in my mind is to do something like this (Cell
is an interface, Sphere
and Rectangle
implements Cell
. I can set a boolean flag called sphere
after reading the input data):
Cell startcell;
if (sphere)
startcell = new Sphere(0);
else
startcell = new Rectangle(0);
But is this good design?
-
1@BalusC Well why not write an answer instead?yannis– yannis2011年12月01日 20:40:38 +00:00Commented Dec 1, 2011 at 20:40
-
Thanks. So from the responses and wiki it looks to me that this way to instantiate is good enough.Captain Jack sparrow– Captain Jack sparrow2011年12月01日 20:43:22 +00:00Commented Dec 1, 2011 at 20:43
2 Answers 2
Looks like Factory pattern, which is quite "endorsed" by design gurus, so to speak. See bottom of that Wikipedia pages for existing creation patterns for OOP languages, like Java.
-
Well, I'm not sure, but Wikipedia page I've linked shows Java snippets very similar to OP's (e.g.,
ImageReader
example).Victor Sorokin– Victor Sorokin2011年12月01日 20:40:00 +00:00Commented Dec 1, 2011 at 20:40 -
quite "endorsed" by design gurus, so to speak
is not a good enough reference for your answer. Who are these gurus? Can you provide sources that they endorse the Factory pattern for situations similar to the question? Can you provide any reference or reasoning for why you suggest the Factory pattern?yannis– yannis2011年12月01日 20:44:57 +00:00Commented Dec 1, 2011 at 20:44 -
@BalusC: See my answer to programmers.stackexchange.com/questions/81838/…. Victor is absolutely correct.pdr– pdr2011年12月01日 20:49:45 +00:00Commented Dec 1, 2011 at 20:49
The if/else implementation is not very scalable - as soon as you add a Cube, you have to add another if condition. It's not really a design pattern, but Java can handle this with reflection. You can read the class name from some config and instantiate it and verify that it implements the appropriate interface. Just a side note, the Spring framework can do this for you too.
// className is read from config, etc
Class instantation = Class.forName(className);
if (!Cell.class.isAssignableFrom(instantation))
throw new Exception("Not a Cell!");
Cell cell = (Cell) instantion.newInstance();
-
1I have read that reflection should be used minimally. That isnt true?Captain Jack sparrow– Captain Jack sparrow2011年12月01日 20:51:51 +00:00Commented Dec 1, 2011 at 20:51
-
Not always. I guess arguments there would go like 'reflection is slow and hard to maintain'. While this is generally true, in case like yours, reflection can pay off. Especially, if these objects you going to create are "high-level" objects and you don't need to create lot of them during runtime.Victor Sorokin– Victor Sorokin2011年12月01日 20:54:34 +00:00Commented Dec 1, 2011 at 20:54
-
How is if/else not scalable? It is easily converted to a switch/case, which is the exact point where you should be thinking about the factory method pattern (see Fowler, Refactoring).pdr– pdr2011年12月01日 20:54:56 +00:00Commented Dec 1, 2011 at 20:54
-
I guess, jeff's point is the case when reflection allows to parameterize, e.g., via property, which type to instantiate, without recompilation of factory code.Victor Sorokin– Victor Sorokin2011年12月01日 20:57:26 +00:00Commented Dec 1, 2011 at 20:57
-
Reflection breaks refactoring.kevin cline– kevin cline2011年12月02日 00:25:22 +00:00Commented Dec 2, 2011 at 0:25