creating objects and polymorphism
design-patterns, java, polymorphism
Solution
Question is "if" you need a factory. The factory is meant to manage the creation of instances an not so much the behavior of related instances.
Otherwise, you're just looking at basic inheritance. Something like..
class Actor{
public void act(){
System.out.println("I act..");
}
}
class StuntActor extends Actor {
public void act(){
System.out.println("I do fancy stunts..");
}
}
class VoiceActor extends Actor {
public void act(){
System.out.println("I make funny noises..");
}
}
To Use, you can just instantiate the type of actor you need directly.
Actor fred = new Actor();
Actor tom = new VoiceActor();
Actor sally = new StuntActor();
fred.act();
tom.act();
sally.act();
Output:
I act..
I make funny noises..
I do fancy stunts..
EDIT:
If you need to centralize the creation of the Actors..aka vis a Factory, you will not be able to get away from some kind of switching logic--in which case..i'll typically use an enumeration for readability:
public class Actor{
public enum Type{ REGULAR, VOICE, STUNT }
public static Actor Create(Actor.Type type){
switch(type) {
case VOICE:
return new VoiceActor();
case STUNT:
return new StuntActor();
case REGULAR:
default:
return new Actor();
}
}
public void act(){
System.out.println("I act..");
}
}
Usage:
Actor some_actor = Actor.Create(Actor.Type.VOICE);
some_actor.act();
Output:
I make funny noises..
Problem
I want to avoid using tagged classes and big if-else blocks or switch statement and use polymorphism with a class hierarchy instead, which I believe is better practice. For example, something like the below, where the choice of executed method is dependent only one one field of an object of type Actor. ``` switch(actor.getTagField()) { case 1: actor.act1(); break; case 2: actor.act2(); break; [...] } ``` would become ``` actor.act(); ``` and the act method would be overridden in subclasses of Actor. However, the most obvious way to decide at runtime which subclass to instantiate looks awfully similar to the original: ``` Actor newActor(int type) { switch(type) { case 1: return new Actor1(); case 2: return new Actor2(); [...] } } ``` so it seems like nothing has really been gained; the logic has just been moved. What is a better way to do this? The only way I can come up with involved implementing a factory class for each subclass of Actor, but this seems rather cumbersome for such a simple problem. Am I overthinking this? It just seems like there's no point making the original change if I just do pretty much the same thing elsewhere.