# Purpose
The Factory Method defines an interface for creating an object, but lets subclasses decide which class to instantiate. It defers instantiation to subclasses.
# Problem
The need to create objects without specifying the exact class of the object that will be created. In a kitchen example: we must prepare a dish, but we don't know if it will be a soup, a salad, or a dessert until the last moment.
# Solution
The solution offered by the Factory Method is:
-
Define an object creation interface: Create an abstract interface or method for object creation.
-
Delegate creation to subclasses: Subclasses will have the concrete implementation for object creation.
As a result, the client can work with interfaces or abstract classes without having to know the concrete classes. It's like having a general "prepare a dish" method, but the sub-recipes determine the specific ingredients and procedures.
# Structure
# Participants
-
Creator: Defines the abstract method for object creation.
-
ConcreteCreator: Implements the factoryMethod. Returns an instance of the ConcreteProduct.
-
Product: Interface or abstract class of the objects to be created.
-
ConcreteProduct: Specific implementation of the created product.
# When to Use It
-
A class can't anticipate the class of objects it must create.
-
A class wants its subclasses to specify the objects it creates.
# Advantages
-
verified
Flexibility
By delegating object creation to subclasses.
-
verified
Decoupling
Separates construction code from the product's own code.
# Disadvantages
-
warning
Complexity
Requires creation of multiple subclasses, increasing development time.
# Example: Document Management
Think of a document management system where users can create different types (text, spreadsheets, presentations). Each type has specific features but share basic functionalities like open, close, and save.
Problem
Users must be able to create a document, but the exact type will depend on user choice at runtime.
Proposed solution
We implement a Factory Method that lets subclasses decide which document class to instantiate. DocumentManager acts as the client.
# Java Code
abstract class Document {
public abstract void open();
public abstract void close();
public abstract void save();
}
class TextDocument extends Document {
@Override
public void open() { /* ... */ }
@Override
public void close() { /* ... */ }
@Override
public void save() { /* ... */ }
}
abstract class DocumentCreator {
public abstract Document createDocument();
}
public class TextDocumentCreator extends DocumentCreator {
@Override
public Document createDocument() {
return new TextDocument();
}
}
public class DocumentManager {
public static void main(String[] args) {
DocumentCreator creator = new TextDocumentCreator();
Document doc = creator.createDocument();
doc.open();
doc.save();
doc.close();
}
}
# Mapping Participants
- DocumentCreator (Creator): Defines the factory method.
- TextDocumentCreator (ConcreteCreator): Implements the method to return a specific type.
- Document (Product): Defines the common interface.
- TextDocument (ConcreteProduct): Specific implementation.
- DocumentManager (Client): Decides what document to create.
# Conclusions
This approach keeps code flexible and extensible, easily allowing the addition of new document types without modifying existing code.
# Related Patterns
Abstract Factory
Factory Method creates a single object; Abstract Factory creates a family.
Builder
Builder constructs step-by-step; Factory Method in a single step.
Prototype
Prototype uses cloning rather than subclassing the Creator.
Template Method
Factory methods are often called from within Template Methods.