Keywords: Design Patterns | Factory Method Pattern | Abstract Factory Pattern | Creational Patterns | Software Architecture
Abstract: This article deeply explores common naming confusion in design patterns, focusing on the core differences between Factory Method Pattern and Abstract Factory Pattern. By clarifying the multiple meanings of the term "factory", it systematically explains the essential distinctions in intent, structure, and application scenarios of both patterns, providing clear code examples to illustrate proper selection and usage of these creational patterns.
Naming Confusion in Design Patterns
In the study and application of software design patterns, the term "factory" often causes confusion. Many developers mistakenly believe there exists an independent "Factory Pattern", when in fact in classical design pattern classification, there are only two distinct patterns: Factory Method Pattern and Abstract Factory Pattern.
Multiple Meanings of the Term "Factory"
The term "factory" may refer to different concepts in various contexts:
- As a shorthand for "Abstract Factory Pattern"
- As a shorthand for "Factory Method Pattern"
- As a general term for all factory-related creational patterns
- Incorrectly referring to factories that create other factories
Core Characteristics of Factory Method Pattern
The Factory Method Pattern implements object creation through inheritance mechanism. This pattern defines an interface for creating an object, but lets subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
Here is a code example of Factory Method Pattern:
// Abstract product interface
public interface IFruit {
void consume();
}
// Concrete product implementations
public class Apple implements IFruit {
public void consume() {
System.out.println("Eating an apple");
}
}
public class Banana implements IFruit {
public void consume() {
System.out.println("Eating a banana");
}
}
// Creator abstract class
public abstract class FruitCreator {
// Factory method
public abstract IFruit createFruit();
public void someOperation() {
IFruit fruit = createFruit();
fruit.consume();
}
}
// Concrete creators
public class AppleCreator extends FruitCreator {
public IFruit createFruit() {
return new Apple();
}
}
public class BananaCreator extends FruitCreator {
public IFruit createFruit() {
return new Banana();
}
}
Core Characteristics of Abstract Factory Pattern
The Abstract Factory Pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes through composition mechanism. This pattern involves a super-factory that creates other factories, where each generated factory can provide objects according to the factory pattern.
Here is a code example of Abstract Factory Pattern:
// Abstract product interfaces
public interface IButton {
void render();
}
public interface ICheckbox {
void render();
}
// Concrete products - Windows style
public class WindowsButton implements IButton {
public void render() {
System.out.println("Rendering Windows style button");
}
}
public class WindowsCheckbox implements ICheckbox {
public void render() {
System.out.println("Rendering Windows style checkbox");
}
}
// Concrete products - Mac style
public class MacButton implements IButton {
public void render() {
System.out.println("Rendering Mac style button");
}
}
public class MacCheckbox implements ICheckbox {
public void render() {
System.out.println("Rendering Mac style checkbox");
}
}
// Abstract factory
public interface GUIFactory {
IButton createButton();
ICheckbox createCheckbox();
}
// Concrete factories
public class WindowsFactory implements GUIFactory {
public IButton createButton() {
return new WindowsButton();
}
public ICheckbox createCheckbox() {
return new WindowsCheckbox();
}
}
public class MacFactory implements GUIFactory {
public IButton createButton() {
return new MacButton();
}
public ICheckbox createCheckbox() {
return new MacCheckbox();
}
}
// Client code
public class Application {
private IButton button;
private ICheckbox checkbox;
public Application(GUIFactory factory) {
button = factory.createButton();
checkbox = factory.createCheckbox();
}
public void render() {
button.render();
checkbox.render();
}
}
Core Differences Between the Two Patterns
Creation Mechanism Difference: Factory Method Pattern uses inheritance, implementing specific creation logic through subclasses; Abstract Factory Pattern uses composition, creating product families through factory objects.
Product Scope Difference: Factory Method Pattern typically handles creation of single product families; Abstract Factory Pattern handles creation of multiple related product families, ensuring compatibility between products.
Extensibility Difference: Factory Method Pattern extends by adding new subclasses; Abstract Factory Pattern extends by implementing new factory interfaces.
Application Scenario Selection Guide
When to use Factory Method Pattern:
- When a class cannot anticipate the class of objects it must create
- When a class wants its subclasses to specify the objects it creates
- When you need to decouple product creation from usage
When to use Abstract Factory Pattern:
- When a system should be independent of how its products are created, composed, and represented
- When a system should be configured with one of multiple families of products
- When you need to emphasize a family of related product objects designed to be used together
- When you want to provide a product class library and reveal only their interfaces, not implementations
Avoiding Common Misunderstandings
It is particularly important to emphasize that there is no such thing as a "factory of factories" pattern. If following certain incorrect understandings, infinite recursive definitions would appear: AbstractFactory implements IAbstractFactory, and IAbstractFactory needs to be created by AbstractAbstractFactory, which is clearly unreasonable.
The Abstract Factory Pattern itself is the ultimate pattern for handling factory creation, and there is no need nor should there be additional factory layers built on top of it. The correct understanding is: Abstract Factory Pattern creates product families, not other factories.
Conclusion
The key to understanding Factory Method Pattern and Abstract Factory Pattern lies in recognizing their essential differences: Factory Method focuses on the creation process of single products through subclassing; Abstract Factory focuses on the creation of product families through interface composition. Properly distinguishing these two patterns and avoiding terminology confusion is crucial for effectively applying design patterns.