The Observer pattern is a behavioral design pattern that allows objects to establish a one-to-many dependency relationship. In this pattern, an object, known as the subject or observable, maintains a list of dependents, known as observers, and notifies them automatically of any state changes. The observers can then react to these notifications and perform appropriate actions. The Observer pattern promotes loose coupling between the subject and observers, enabling a flexible and maintainable code structure.

In PHP, you can implement the Observer pattern using built-in language features or by creating custom classes.

Let's explore an example using custom classes:

// Subject interface defines the contract for the subject (observable) object.
interface Subject {
    public function attach(Observer $observer);
    public function detach(Observer $observer);
    public function notify();
}

// Concrete subject class implements the subject interface.
class WeatherStation implements Subject {
    private $temperature;
    private $observers;

    public function __construct() {
        $this->observers = [];
    }

    public function attach(Observer $observer) {
        $this->observers[] = $observer;
    }

    public function detach(Observer $observer) {
        $index = array_search($observer, $this->observers);
        if ($index !== false) {
            unset($this->observers[$index]);
        }
    }

    public function notify() {
        foreach ($this->observers as $observer) {
            $observer->update($this->temperature);
        }
    }

    public function setTemperature($temperature) {
        $this->temperature = $temperature;
        $this->notify();
    }
}

// Observer interface defines the contract for the observer objects.
interface Observer {
    public function update($temperature);
}

// Concrete observer classes implement the observer interface.
class UserInterface implements Observer {
    public function update($temperature) {
        echo "Updating user interface. Current temperature: " . $temperature . " degrees Celsius.<br>";
    }
}

class Logger implements Observer {
    public function update($temperature) {
        echo "Logging temperature: " . $temperature . " degrees Celsius.<br>";
    }
}

In this example, we have a WeatherStation class that acts as the subject. It implements the Subject interface, which defines methods for attaching, detaching, and notifying observers. The subject maintains an array of observers and notifies them whenever the temperature changes.

The Factory pattern is a creational design pattern that provides an interface for creating objects but delegates the actual object instantiation to subclasses or specialized factory methods. It encapsulates the object creation logic, promoting loose coupling and flexibility in object creation. In PHP, the Factory pattern can be implemented using different approaches, such as simple factory, factory method, or abstract factory.

 

Simple Factory:

The simple factory, also known as the static factory, is the simplest form of the Factory pattern. It involves a single factory class responsible for creating objects based on input parameters. Here's an example:

// Product interface defines the contract for the products.
interface Product {
    public function getName();
}

// Concrete products implement the product interface.
class ConcreteProductA implements Product {
    public function getName() {
        return 'Product A';
    }
}

class ConcreteProductB implements Product {
    public function getName() {
        return 'Product B';
    }
}

// Simple factory class that creates products based on the input.
class SimpleFactory {
    public static function createProduct($type) {
        switch ($type) {
            case 'A':
                return new ConcreteProductA();
            case 'B':
                return new ConcreteProductB();
            default:
                throw new InvalidArgumentException("Invalid product type.");
        }
    }
}

// Usage example:
$productA = SimpleFactory::createProduct('A');
echo $productA->getName();  // Output: Product A

$productB = SimpleFactory::createProduct('B');
echo $productB->getName();  // Output: Product B

In this example, we have a Product interface representing the contract for all products. The ConcreteProductA and ConcreteProductB classes implement the Product interface. The SimpleFactory class provides a static method createProduct() that accepts a type parameter and returns the appropriate concrete product instance based on the type.

 

The Strategy pattern is a behavioral design pattern that enables an object to dynamically change its behavior at runtime by encapsulating different algorithms or strategies within interchangeable objects.

It promotes the principle of composition over inheritance and allows for flexible and modular code. In PHP, the Strategy pattern can be implemented using interfaces and multiple classes that implement those interfaces.

Here is an example implementation in PHP:

The Bridge pattern is a structural design pattern that decouples an abstraction from its implementation, allowing them to vary independently. It provides a way to handle complex class hierarchies by separating them into two separate hierarchies: the abstraction hierarchy and the implementation hierarchy. This pattern promotes loose coupling and flexibility in designing and evolving systems. In PHP, the Bridge pattern can be implemented using interfaces and classes that implement those interfaces.

 

Example implementation in PHP: