Currently I have a method that acts as a factory based on a given String. For example:
public Animal createAnimal(String action)
{
if (action.equals(\"M
And what do people think about using Class.newInstance() inside Tom Hawtin's answer? This will avoid us from storing unnecessary anonymous classes in memory? Plus code will be more clean.
It will look something like this:
private static final Map<String,Class> factoryMap =
Collections.unmodifiableMap(new HashMap<String,Class>() {{
put("Meow", Cat.class);
put("Woof", Dog.class);
}});
public Animal createAnimal(String action) {
return (Animal) factoryMap.get(action).newInstance();
}
If you don't have to use Strings, you could use an enum type for the actions, and define an abstract factory method.
...
public enum Action {
MEOW {
@Override
public Animal getAnimal() {
return new Cat();
}
},
WOOF {
@Override
public Animal getAnimal() {
return new Dog();
}
};
public abstract Animal getAnimal();
}
Then you can do things like:
...
Action action = Action.MEOW;
Animal animal = action.getAnimal();
...
It's kind of funky, but it works. This way the compiler will whine if you don't define getAnimal() for every action, and you can't pass in an action that doesn't exist.
I'd look to retrieve an Enum representation of the String and switch on that.
You already selected the answer to that question, but that could still help.
Although I am a .NET/C# developer, this is really a general OOP problem. I have run in the same kind of problem and I have found a nice solution (I think) using an IoC Container.
If you don't use one yet, that is probably a good reason to start. I don't know IoC containers in Java, but I assume there must be one with similar features.
What I had was a Factory that contains a reference to the IoC container, which is resolved by the container itself (in the BootStrapper)
...
public AnimalFactory(IContainer container)
{
_container = container;
}
You can then setup your IoC container to resolve the correct types based on a key (the sound in your example). It would abstracts completely the concrete classes that your factory needs to return.
in the end, your factory method is shrunk down to this :
...
public Createable CreateAnimal(string action)
{
return _container.Resolve<Createable>(action);
}
This stackoverflow question illustrates the same kind of problem with real world elements and the validated answer shows a draft of my solution (pseudo code). I later wrote a blog post with the real pieces of code where it is much clearer.
Hope this can help. But it might be overkill in simple cases. I used that because I had 3 levels of dependencies to resolve, and an IoC container already assembling all my components.