Factory Method Design Pattern in PHP

1. Definition

The Factory Method Design Pattern provides an interface for creating instances of a class, but allows subclasses to alter the type of objects that will be created. Instead of calling a class constructor directly, a factory method is used to create the object.

2. Problem Statement

Imagine you are building a UI library, and you need to provide a way to create different types of buttons. If you hardcode the instantiation process, every time a new button type is added, the main code needs to change. This violates the open/closed principle.

3. Solution

The Factory Method pattern solves this by defining a separate method for creating objects, allowing subclasses to decide which class to instantiate. The factory method is typically defined in an interface, which the concrete classes implement.

4. Real-World Use Cases

1. GUI libraries where each OS provides a different implementation of a button.

2. Payment gateway integration where each provider has a different implementation.

5. Implementation Steps

1. Create an interface (or an abstract class) with the factory method.

2. Create concrete classes implementing this interface and overriding the factory method.

3. Use the factory method instead of direct constructors to create objects.

6. Implementation in PHP

<?php
// 1. Create an interface with the factory method
interface ButtonFactory {
    public function createButton();
}
class WindowsButtonFactory implements ButtonFactory {
    public function createButton() {
        return new WindowsButton();
    }
}
class LinuxButtonFactory implements ButtonFactory {
    public function createButton() {
        return new LinuxButton();
    }
}
class WindowsButton {
    public function render() {
        return "Windows Button Rendered!";
    }
}
class LinuxButton {
    public function render() {
        return "Linux Button Rendered!";
    }
}
// Client code
$factory = new WindowsButtonFactory();
$button = $factory->createButton();
echo $button->render();
?>

Output:

Windows Button Rendered!

Explanation:

We defined a ButtonFactory interface with a method createButton(). Then, we have two concrete factories: WindowsButtonFactory and LinuxButtonFactory, each creating their respective button types. In the client code, we use the WindowsButtonFactory to create a Windows button and then render it.

By using the Factory Method pattern, we can easily introduce more button types (like a MacButton) without changing the client code or the main interface, adhering to the open/closed principle.

7. When to use?

Use the Factory Method Pattern when:

1. You want to provide a generic interface for creating objects but allow subclasses to determine the exact type of object to create.

2. The creation logic of the objects is complex and should be separated from the main logic.

3. You need a centralized point to manage and control object creation.


Comments