Definition

Concept

Factory pattern: creational design pattern abstracting object instantiation. Provides interface for creating objects in superclass but allows subclasses to alter type of created objects.

Scope

Focus: object creation mechanism. Separation: creation logic from usage logic. Result: flexible, extensible code.

Context

Used when system requires dynamic object creation based on input or configuration without specifying exact class.

Purpose

Abstraction of Instantiation

Hide concrete classes. Client code interacts with interfaces or abstract classes.

Encapsulation of Creation Logic

Centralize creation code to reduce duplication and errors.

Support for Polymorphism and Extensibility

Enable adding new product types with minimal impact on existing code.

Types of Factory Patterns

Simple Factory

Not a formal pattern. Static method creates instances based on parameters.

Factory Method

Defines interface for creating an object but lets subclasses decide which class to instantiate.

Abstract Factory

Creates families of related objects without specifying concrete classes.

Structure

Participants

Product: interface or abstract class defining object. ConcreteProduct: implements Product. Creator (Factory): declares factory method. ConcreteCreator: overrides factory method to return ConcreteProduct.

Collaborations

Client uses Creator interface to create Product. Creator delegates instantiation to ConcreteCreator.

UML Overview

Factory method pattern: Creator contains factoryMethod(). ConcreteCreator implements factoryMethod() to instantiate ConcreteProduct.

ComponentRole
ProductDefines interface for objects
ConcreteProductImplements Product interface
Creator (Factory)Declares factory method
ConcreteCreatorOverrides factory method to instantiate ConcreteProduct

Implementation Details

Factory Method Signature

Return type: Product interface or abstract class. Parameters: optional, to decide concrete product.

Subclassing

ConcreteCreator subclasses override factory method to instantiate specific ConcreteProduct.

Client Interaction

Client calls factory method via Creator interface, unaware of concrete class.

abstract class Creator { abstract Product factoryMethod(); void someOperation() { Product product = factoryMethod(); // Use product }}class ConcreteCreator extends Creator { Product factoryMethod() { return new ConcreteProduct(); }}

Advantages

Decoupling

Separates client code from concrete classes.

Extensibility

New products added without modifying client or factory interface.

Single Responsibility

Factory encapsulates creation logic, promoting cleaner code.

Testability

Mock factories enable easier unit testing.

Disadvantages

Increased Complexity

Additional classes and interfaces increase code base size.

Overhead

Factory indirection adds runtime overhead and cognitive load.

Potential for Misuse

Unnecessary abstraction if few product variants exist.

Usage Scenarios

When to Use

System requires flexible object creation. New product types expected. Client unaware of concrete classes.

Where to Avoid

Simple instantiation suffices. No foreseeable product changes.

Common Applications

GUI toolkit widgets, database drivers, cross-platform resource loading.

Comparison with Other Patterns

Simple Factory vs Factory Method

Simple Factory: static method, no inheritance. Factory Method: relies on subclassing.

Factory Method vs Abstract Factory

Factory Method: creates one product. Abstract Factory: creates families of related products.

Factory vs Builder

Factory: creates objects in one step. Builder: creates complex objects step-by-step.

Code Example

Scenario

Shape creation with Factory Method pattern.

Classes

Shape (interface), Circle and Square (concrete), ShapeFactory (creator), CircleFactory and SquareFactory (concrete creators).

interface Shape { void draw();}class Circle implements Shape { public void draw() { System.out.println("Drawing Circle"); }}class Square implements Shape { public void draw() { System.out.println("Drawing Square"); }}abstract class ShapeFactory { abstract Shape createShape(); void render() { Shape shape = createShape(); shape.draw(); }}class CircleFactory extends ShapeFactory { Shape createShape() { return new Circle(); }}class SquareFactory extends ShapeFactory { Shape createShape() { return new Square(); }}// Client codeShapeFactory factory = new CircleFactory();factory.render(); // Outputs "Drawing Circle"

Best Practices

Interface Consistency

Factory methods should maintain consistent signatures for ease of use.

Avoid Over-Generalization

Do not abstract prematurely; apply factory only when multiple products exist.

Documentation

Clearly document factory responsibilities and product variants.

Unit Testing

Mock factories to isolate tests from concrete implementations.

References

  • Gamma, E., Helm, R., Johnson, R., Vlissides, J., "Design Patterns: Elements of Reusable Object-Oriented Software," Addison-Wesley, 1994, pp. 87-122.
  • Freeman, E., Robson, E., Bates, B., Sierra, K., "Head First Design Patterns," O'Reilly Media, 2004, pp. 75-110.
  • Shalloway, A., Trott, J.R., "Design Patterns Explained: A New Perspective on Object-Oriented Design," Addison-Wesley, 2002, pp. 45-70.
  • Martin, R.C., "Agile Software Development, Principles, Patterns, and Practices," Prentice Hall, 2003, pp. 150-165.
  • Buschmann, F., Meunier, R., Rohnert, H., Sommerlad, P., Stal, M., "Pattern-Oriented Software Architecture: A System of Patterns," Wiley, 1996, pp. 123-140.