factory pattern dynamic approach

use reflection

public Pet getPet(String petType)
{
     Pet _pet = (Pet)Class.forName(petType).newInstance();
     return _pet;
}

you need to change your arguments from 'bark','quack' to 'Dog' and 'Duck' etc


I think there is a dynamic approach:

  1. In your factory you need a Map<String, Class<? extends Pet>>
  2. In static constructor of every class, which extends Pet, register it with such map.
  3. Than creating a class will be just map.get(pet).newInstance ( you'd have to check for nulls, of course)

The idea behind the factory pattern is to let you dynamically instantiate objects whose types you don't necessarily know about at design time.

Having a big if block defeats that purpose.

The effective way to implement this pattern is to also have a factory for each type, which implements a base factory interface and has the ability to instantiate a new object of that type (by the way, in Java, the built-in Class is an example of such a factory).

Then you register a map of names/ids/etc. to instances of these individual factories at runtime. When it's time to instantiate one of the types, you look up the factory in the map by name and use that to instantiate a new object of that type.

How you register individual factories in the map is totally up in the air. You could register some explicitly, you could scan a configuration file, etc.

Essentially you want to replace your if block with a map that is dynamically created at runtime.

You don't even need to solely use a preregistered "map" - sometimes it may be appropriate to figure out how to create an object with a given name on the fly, or a combination of the two (e.g. Class.forName() searches the class path if it can't find the class already loaded). The point is the translation of the name to the class type can take place without the base factory actually knowing what the class type is.

It's worth noting that Java reflection provides a very workable factory implementation already via Class.forName() and/or Class.newInstance(), so consider using that instead of reinventing the wheel if it makes sense.