Factory Method Pattern
The Factory Method pattern is a creational design pattern that provides an interface for creating objects in a superclass, but allows subclasses to alter the type of objects that will be created.
In other words, instead of calling the constructor directly to create an object, the Factory Method pattern uses a factory method to create the object. This method is typically defined in an interface, which is implemented by concrete classes.
The Factory Method pattern is particularly useful when the exact types of objects and dependencies are not known until runtime. It also promotes loose coupling by eliminating the need for a class to have knowledge of the exact class name to create an instance.
Here's a simple example in Java:
public interface Animal {
void speak();
}
public class Dog implements Animal {
public void speak() {
System.out.println("Woof!");
}
}
public class Cat implements Animal {
public void speak() {
System.out.println("Meow!");
}
}
public abstract class AnimalFactory {
public abstract Animal createAnimal();
}
public class DogFactory extends AnimalFactory {
public Animal createAnimal() {
return new Dog();
}
}
public class CatFactory extends AnimalFactory {
public Animal createAnimal() {
return new Cat();
}
}
// Client code
public class Client {
public static void main(String[] args) {
AnimalFactory dogFactory = new DogFactory();
Animal dog = dogFactory.createAnimal();
dog.speak(); // Outputs: Woof!
AnimalFactory catFactory = new CatFactory();
Animal cat = catFactory.createAnimal();
cat.speak(); // Outputs: Meow!
}
}
In this example, Animal
is the product that the client (Client
class) interacts with. Dog
and Cat
are concrete products. AnimalFactory
is the creator that declares the factory method createAnimal()
which returns an Animal
. DogFactory
and CatFactory
are concrete creators that implement createAnimal()
to produce Dog
and Cat
instances.
This pattern is useful when there's a need to decouple the client code that uses a product from the code that actually creates it, or when there's a need to provide a hook for subclasses to decide which class to instantiate, or when a class cannot anticipate the class of objects it must create.