🏭 Design Patterns in JavaScript — Part 2: The Factory Pattern
Imagine this…
You’re building a form builder. Each field type — text, email, checkbox — needs its own logic, validation, and rendering.
Do you create separate classes and use if statements all over the place?
Or do you use a clean abstraction that gives you the right object on demand?
That’s the beauty of the Factory Pattern — it lets you create objects without exposing the creation logic , and lets you decide the type at runtime.
Let’s break it down — no fluff, just real JavaScript examples.
🧠 Why Factory?
You use it when:
- You need to create many types of objects
- Their structure is mostly the same, but behavior differs
- You don’t want to hardcode if-else chains everywhere
🛠 Real Use Case: React Form Field Generator
Let’s say you’re building dynamic form components in React:
function createFormField(type) {
switch (type) {
case 'text':
return <input type="text" />;
case 'email':
return <input type="email" />;
case 'checkbox':
return <input type="checkbox" />;
default:
return <input />;
}
}
Usage:
const field = createFormField('email');
✅ Centralized logic
✅ Easier to maintain
✅ You can even return entire components or class instances
📦 Backend Example: Dynamic API Handler
Imagine this in an Express API:
function createUserHandler(type) {
const handlers = {
admin: () => new AdminUser(),
guest: () => new GuestUser(),
default: () => new BasicUser(),
};
return (handlers[type] || handlers.default)();
}
Now you don’t write:
if (type === 'admin') return new AdminUser();
✅ Clean
✅ Extendable
✅ Predictable
💡 Advanced Use: Strategy + Factory Combo
You can use Factory to return strategies too:
function getPaymentStrategy(mode) {
const strategies = {
stripe: () => new StripePayment(),
razorpay: () => new RazorpayPayment(),
cod: () => new CashOnDelivery(),
};
return (strategies[mode] || strategies.cod)();
}
const payment = getPaymentStrategy('stripe');
payment.pay(); // executes Stripe logic
🧪 Real Projects That Use Factory
✅ Up Next: Observer Pattern
In Part 3, we’ll explore how you can use the Observer Pattern to:
- Listen to events
- Build state subscriptions
- Communicate across components/services
👉 Follow the series on Medium — we’re going one pattern at a time with real code and clean examples.