Design Patterns
- Chapter 1: Introduction to Design Patterns
- Chapter 2: Creational Design Patterns
- Chapter 3: Singleton Pattern
- Chapter 4: Factory Method Pattern
- Chapter 5: Abstract Factory Pattern
- Chapter 6: Builder Pattern
- Chapter 7: Prototype Pattern
- Chapter 8: Structural Design Patterns
- Chapter 9: Adapter Pattern
- Chapter 10: Bridge Pattern
- Chapter 11: Composite Pattern
- Chapter 12: Decorator Pattern
- Chapter 13: Facade Pattern
- Chapter 14: Flyweight Pattern
- Chapter 15: Proxy Pattern
- Chapter 16: Behavioral Design Patterns
- Chapter 17: Chain of Responsibility Pattern
- Chapter 18: Command Pattern
- Chapter 19: Interpreter Pattern
- Chapter 20: Iterator Pattern
- Chapter 21: Mediator Pattern
- Chapter 22: Memento Pattern
- Chapter 23: Observer Pattern
- Chapter 24: State Pattern
- Chapter 25: Strategy Pattern
- Chapter 26: Template Method Pattern
- Chapter 27: Visitor Pattern
- Chapter 28: Design Patterns in Real-World Applications
- Chapter 29: Pros and Cons of Design Patterns
- Chapter 30: Best Practices for Using Design Patterns
Tutorials – Design Patterns
Chapter 4: Factory Method Pattern
The Factory Method Pattern is a creational design pattern that provides an interface for creating objects in a super class, but allows subclasses to alter the type of objects that will be created. In this chapter, we will explore the Factory Method Pattern, its use cases, implementation, and benefits.
Understanding the Factory Method Pattern
The Factory Method Pattern is all about creating objects. It defines an interface for creating objects but lets subclasses alter the type of objects that will be created. This is achieved by creating a separate factory method for each type of object that needs to be created.
Key Characteristics of Factory Method Pattern:
- Abstract Creator: The pattern defines an abstract creator (interface or base class) that declares the factory method, which returns an object of a product type.
- Concrete Creators: Subclasses of the abstract creator implement the factory method, each providing their own implementation to create a specific type of product.
- Abstract Product: The pattern also defines an abstract product (interface or base class) that represents the type of objects to be created.
- Concrete Products: Subclasses of the abstract product are the actual product implementations.
- Loose Coupling: The Factory Method Pattern promotes loose coupling between the creator and the product. The creator class doesn’t need to know the concrete product classes, only the abstract product.
Use Cases for the Factory Method Pattern
The Factory Method Pattern is used in various scenarios where object creation needs to be flexible and customizable. Some common use cases include:
1. GUI Libraries:
In graphical user interface (GUI) libraries, the Factory Method Pattern is often used to create platform-specific UI elements. For example, a button creator factory can create Windows buttons on a Windows platform and Mac buttons on a Mac platform.
interface Button {
void render();
}
class WindowsButton implements Button {
@Override
public void render() {
// Render a Windows button
}
}
class MacButton implements Button {
@Override
public void render() {
// Render a Mac button
}
}
interface ButtonFactory {
Button createButton();
}
class WindowsButtonFactory implements ButtonFactory {
@Override
public Button createButton() {
return new WindowsButton();
}
}
class MacButtonFactory implements ButtonFactory {
@Override
public Button createButton() {
return new MacButton();
}
}
2. Logging Frameworks:
In logging frameworks, the Factory Method Pattern is used to create loggers for different log levels and destinations. Each logger type can be a concrete product.
interface Logger {
void log(String message);
}
class ConsoleLogger implements Logger {
@Override
public void log(String message) {
System.out.println("Console: " + message);
}
}
class FileLogger implements Logger {
@Override
public void log(String message) {
// Log to a file
}
}
interface LoggerFactory {
Logger createLogger();
}
class ConsoleLoggerFactory implements LoggerFactory {
@Override
public Logger createLogger() {
return new ConsoleLogger();
}
}
class FileLoggerFactory implements LoggerFactory {
@Override
public Logger createLogger() {
return new FileLogger();
}
}
3. Game Development:
In game development, the Factory Method Pattern can be used to create different types of game entities like characters, enemies, and power-ups. Each entity type can have its factory.
abstract class GameEntity {
abstract void render();
}
class Character extends GameEntity {
@Override
void render() {
// Render the character
}
}
class Enemy extends GameEntity {
@Override
void render() {
// Render the enemy
}
}
abstract class GameEntityFactory {
abstract GameEntity createEntity();
}
class CharacterFactory extends GameEntityFactory {
@Override
GameEntity createEntity() {
return new Character();
}
}
class EnemyFactory extends GameEntityFactory {
@Override
GameEntity createEntity() {
return new Enemy();
}
}
Implementing the Factory Method Pattern
The Factory Method Pattern can be implemented in various programming languages, including Java, C++, and Python. The key is to define an abstract creator class or interface and concrete creator classes that implement the factory method to create specific product objects.
Java Implementation:
In Java, the Factory Method Pattern can be implemented using abstract classes and method overriding.
abstract class Product {
abstract void performAction();
}
class ConcreteProductA extends Product {
@Override
void performAction() {
// Implement action for ConcreteProductA
}
}
class ConcreteProductB extends Product {
@Override
void performAction() {
// Implement action for ConcreteProductB
}
}
abstract class Creator {
abstract Product factoryMethod();
void someOperation() {
// ...
Product product = factoryMethod();
product.performAction();
// ...
}
}
class ConcreteCreatorA extends Creator {
@Override
Product factoryMethod() {
return new ConcreteProductA();
}
}
class ConcreteCreatorB extends Creator {
@Override
Product factoryMethod() {
return new ConcreteProductB();
}
}
Python Implementation:
In Python, the Factory Method Pattern can be implemented using abstract base classes and inheritance.
from abc import ABC, abstractmethod
class Product(ABC):
@abstractmethod
def perform_action(self):
pass
class ConcreteProductA(Product):
def perform_action(self):
# Implement action for ConcreteProductA
pass
class ConcreteProductB(Product):
def perform_action(self):
# Implement action for ConcreteProductB
pass
class Creator(ABC):
@abstractmethod
def factory_method(self):
pass
def some_operation(self):
# ...
product = self.factory_method()
product.perform_action()
# ...
class ConcreteCreatorA(Creator):
def factory_method(self):
return ConcreteProductA()
class ConcreteCreatorB(Creator):
def factory_method(self):
return ConcreteProductB()
Benefits of the Factory Method Pattern
The Factory Method Pattern offers several benefits:
- Flexibility: It allows for the creation of objects to be customized by subclasses, providing flexibility in object creation.
- Extensibility: New product types can be added without modifying existing code, promoting an open-closed principle.
- Code Reusability: The pattern promotes code reusability by separating the product creation from its usage.
- Encapsulation: It encapsulates the object creation details, making the code more maintainable and organized.
Drawbacks and Considerations
While the Factory Method Pattern provides flexibility and extensibility, it also has some considerations:
- Complexity: When there are many product types and corresponding creator classes, the pattern can lead to a complex class hierarchy.
- Abstraction Overhead: It introduces additional abstraction layers, which may not be necessary in simple scenarios.
- Choosing the Right Creator: It’s crucial to choose the right creator for a given situation. The choice of creator can affect the type of product created.
- Naming Conventions: Naming conventions for creators and products should be consistent and clear to maintain code readability.
Conclusion
The Factory Method Pattern is a powerful tool for creating objects in a flexible and extensible way. By defining an abstract creator class or interface, the pattern allows subclasses to determine the type of objects to create. This separation of concerns enhances code organization and makes it easier to add new product types. When used wisely, the Factory Method Pattern can contribute to cleaner and more maintainable code, providing a balance between flexibility and structure in software design.