Back to Engineering Notes
Laravel ConceptsEngineering Note

14. Factory Pattern

Factory Pattern is used to create objects without directly writing object creation logic everywhere.

🧠 Factory Pattern

Factory Pattern is used to create objects without directly writing object creation logic everywhere.

Instead of doing this in many places:

plain text
new EmailNotificationService();
new SmsNotificationService();
new SlackNotificationService();

We centralize object creation in one place:

plain text
Controller / Service
 ↓
Factory
 ↓
Creates correct class

🎯 Simple Idea

Factory decides which class/object to create based on input or condition.

plain text
Input: "email"
 ↓
Factory returns EmailService

Input: "sms"
 ↓
Factory returns SmsService

🧩 Example Use Case

Notification sending:

plain text
email → EmailNotificationService
sms → SmsNotificationService
slack → SlackNotificationService

🧱 Example

plain text
interface NotificationInterface
{
    public function send(string $message): void;
}
plain text
class EmailNotificationService implements NotificationInterface
{
    public function send(string $message): void
    {
        // send email
    }
}
plain text
class SmsNotificationService implements NotificationInterface
{
    public function send(string $message): void
    {
        // send sms
    }
}
plain text
class NotificationFactory
{
    public static function make(string $type): NotificationInterface
    {
        return match ($type) {
            'email' => new EmailNotificationService(),
            'sms' => new SmsNotificationService(),
            default => throw new InvalidArgumentException('Invalid notification type'),
        };
    }
}

🧩 Usage in Service

plain text
class NotificationService
{
    public function send(string $type, string $message): void
    {
        $notification = NotificationFactory::make($type);

        $notification->send($message);
    }
}

📌 Flow

plain text
Request
 ↓
Controller
 ↓
Service
 ↓
Factory
 ↓
Creates correct object
 ↓
Object handles action

🧠 Why I Use Factory Pattern

avoids repeated new ClassName() everywhere
centralizes object creation logic
supports multiple implementations
makes code easier to extend
keeps service/controller cleaner

⚖️ Trade-offs

adds extra class/layer
can be unnecessary for simple object creation
too many factories can make code harder to follow

📌 Practical Rule

Use Factory Pattern when:

plain text
You need to create different classes based on type/condition.

Example:

plain text
payment method → KBZPay / WavePay / Stripe
notification type → Email / SMS / Slack
file storage → Local / S3 / Google Cloud
report type → PDF / Excel / CSV

💬 Summary

> I use the Factory Pattern when object creation depends on conditions, such as notification type, payment provider, report format, or storage driver.

plain text
Input / Type
→ Factory
→ Correct Service/Object
→ Execute Logic

👉 This keeps the code clean, extensible, and easier to maintain.