Back to Overview

Factory Method Pattern

The Factory Method Pattern is a creational design pattern that provides an interface for creating objects but allows subclasses to alter the type of objects that will be created. It addresses the problem of creating product objects without specifying their concrete classes.

Problem

Imagine you're building a logistics management application. In the beginning, it only handled truck transportation, but now you need to add ship transportation. This would require changes to your existing code, which might introduce bugs.

Or consider a cross-platform UI application that needs to create different UI elements depending on the operating system. You'd want a way to create appropriate UI components without hardcoding the specific classes throughout your application.

Creator factoryMethod() ConcreteCreatorA ConcreteCreatorB factoryMethod() factoryMethod() Product ProductA ProductB creates creates

Components

Implementation Example

Here's a basic implementation of the Factory Method pattern in JavaScript:

// Product Interface
class Button {
    render() {
        throw new Error("Button.render() must be implemented");
    }
    
    onClick() {
        throw new Error("Button.onClick() must be implemented");
    }
}

// Concrete Products
class WindowsButton extends Button {
    render() {
        return `<button class="windows-button">Windows Button</button>`;
    }
    
    onClick() {
        return "Windows button clicked";
    }
}

class MacButton extends Button {
    render() {
        return `<button class="mac-button">Mac Button</button>`;
    }
    
    onClick() {
        return "Mac button clicked";
    }
}

// Creator Abstract Class
class Dialog {
    render() {
        // Call the factory method to create a button
        const button = this.createButton();
        
        return `
            <div class="dialog">
                <div class="dialog-content">
                    ${button.render()}
                </div>
            </div>
        `;
    }
    
    // Factory Method
    createButton() {
        throw new Error("Dialog.createButton() must be implemented");
    }
}

// Concrete Creators
class WindowsDialog extends Dialog {
    createButton() {
        return new WindowsButton();
    }
}

class MacDialog extends Dialog {
    createButton() {
        return new MacButton();
    }
}

// Client code
function clientCode(dialog) {
    // Client uses the creator without knowing which concrete creator it's working with
    return dialog.render();
}

// Example usage
function getDialog(os) {
    if (os === "Windows") {
        return new WindowsDialog();
    } else if (os === "Mac") {
        return new MacDialog();
    } else {
        throw new Error("Unknown operating system");
    }
}

// Application
const currentOS = "Windows"; // Could be determined at runtime
const dialog = getDialog(currentOS);
const renderedHTML = clientCode(dialog);

Interactive Demo: UI Components Factory

This demo demonstrates how the Factory Method pattern allows you to create platform-specific UI components. Select a platform to see how different UI components are created by different factories.

// Factory Method demonstration log will appear here

When to Use

Benefits

Real-World Uses