Let’s say I have a Java class
abstract class Base {
abstract void init();
...
}
and I know every derived class will have to call init() after it’s constructed. I could, of course, simply call it in the derived classes’ constructors:
class Derived1 extends Base {
Derived1() {
...
init();
}
}
class Derived2 extends Base {
Derived2() {
...
init();
}
}
but this breaks “don’t repeat yourself” principle rather badly (and there are going to be many subclasses of Base). Of course, the init() call can’t go into the Base() constructor, since it would be executed too early.
Any ideas how to bypass this problem? I would be quite happy to see a Scala solution, too.
UPDATE: Here is a generic version of the Factory Method approach:
interface Maker<T extends Base> {
T make();
}
class Base {
...
static <T extends Base> T makeAndInit(Maker<T> maker) {
T result = maker.make();
result.init();
return result;
}
}
UPDATE 2: This question is basically “how do you use Template Method for constructors”? And the answer seems to be, “You can, but it’s a bad idea”. So I can do a Template Factory (Template Method + Abstract Factory) instead.
What happens in
init()? It’s likely that a better design could eliminate the method altogether, or at least relax the requirement that it execute after the sub-class’ constructor. Be certain thatinit()does not make the object under construction visible to any other threads before the constructor completes, because that creates concurrency bugs.As an (ugly) alternative, an abstract method could be implemented by sub-classes as a pseudo-constructor: