Factory Method

Factory method provides an interface for creating objects in a superclass,
allows subclasses to decide wich class to instantiate.

//Concrete or direct instantiation. Client code with no factory.
$myEmailNotification = new emailNotification;
$mySmsNotification = new smsNotification;

//Abstracted object creation. Client code with a factory-based instantiation.
$myEmailNotification = NotificationFactory::create('email');
$mySmsNotification = NotificationFactory::create('sms');

Factories allow client code to operate on generalizations, this is called coding to an interface, not an implementation and is a fundamental principle in object-oriented programming that promotes flexibility, maintainability, and testability in software design. 

It means that client code should interact with a system through an abstract interface (or abstract class) rather than create the object directly, without worrying about the details of object creation. 

<?php
// interface defines a contract — all notification classes must have a send() method.
interface Notification
{
    public function send(string $to, string $message): void;
}

// Concrete implementations of different notification types

class EmailNotification implements Notification
{
    public function send(string $to, string $message): void
    {
        echo "Sending EMAIL to {$to}: {$message}" . PHP_EOL;
    }
}

class SmsNotification implements Notification
{
    public function send(string $to, string $message): void
    {
        echo "Sending SMS to {$to}: {$message}" . PHP_EOL;
    }
}

class PushNotification implements Notification
{
    public function send(string $to, string $message): void
    {
        echo "Sending PUSH notification to {$to}: {$message}" . PHP_EOL;
    }
}

// The Factory class — decides which notification to create
class NotificationFactory
{
    public static function create(string $type): Notification
    {
        return match (strtolower($type)) {
            'email' => new EmailNotification(),
            'sms'   => new SmsNotification(),
            'push'  => new PushNotification(),
            default => throw new InvalidArgumentException("Unknown notification type: {$type}")
        };
    }
}

// Usage exemple
try {
    $notification = NotificationFactory::create('email');
    $notification->send('user@example.com', 'Your order has been shipped.');

    $notification = NotificationFactory::create('sms');
    $notification->send('+5547999999999', 'Your code is 123456.');

    $notification = NotificationFactory::create('push');
    $notification->send('User123', 'You have a new message.');
} catch (Exception $e) {
    echo "Error: " . $e->getMessage();
}

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *