🧠 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.