Let’s face it — when someone says “design patterns” in a tech interview, most of us immediately panic.
"Ummm... I think, I used a Factory pattern once… maybe? Probably? Singleton I did. When? I do not recall exactly."
The truth on the other hand is you’ve probably used several design patterns already, without knowing it.
First… What Even Are Design Patterns?
Design patterns are just common solutions to common problems in software design.
They're like recipes.
You're not forced to use them, but they help you cook something cleaner, faster, and way less burnt.
They don’t live in libraries. You don’t npm install design-patterns
. They live in your logic and architecture decisions.
This post will help you:
- Recognize the patterns you've already used (even accidentally)
- Understand when and why they actually help
- Feel more confident in interviews
1. From “IF-ELSE Everywhere” to Strategy Pattern
The Problem:
You’re building a discount engine. This is what it looks like,
Function ApplyDiscount(userType, cartAmount) If userType == "Gold" Return cartAmount * 0.8 Else if userType == "Silver" Return cartAmount * 0.9 Else if userType == "Platinum" Return cartAmount - 200 Else Return cartAmount
What started as 3 cases is now 12. Business keeps adding “Just one more rule, please?”
Your function is one "else if" away from burning out, and a new dev working on it cursing you like hell. You can do better than this..
Enter, the Strategy Pattern. Plug different discount behaviours into a common structure.
Class DiscountStrategy Method Apply(cartAmount) Class GoldDiscount Implements DiscountStrategy Method Apply → Return cartAmount * 0.8 Class PlatinumDiscount Implements DiscountStrategy Method Apply → Return cartAmount - 200 Class NoDiscount Implements DiscountStrategy Method Apply → Return cartAmount // Context Class DiscountEngine Constructor(strategy) this.strategy = strategy Method ApplyDiscount(cartAmount) Return this.strategy.Apply(cartAmount)
Why is it better?
- Easily add new strategies (FestiveDiscount? HappyHour? etc.)
- Follows Open-Closed Principle
- Cleaner, testable, flexible
2. From “Manual Object Creation” to Factory Pattern
The Problem:
Your app sends different types of notifications - Email, SMS, Push, maybe Pigeon Post 😜.
And somewhere in the code, you are doing this,
If notificationType == "Email" sender = new EmailSender() Else if notificationType == "SMS" sender = new SmsSender() Else if notificationType == "Push" sender = new PushSender()
Sounds okay? Now imagine this same chunk of code is copied in -
The onboarding flow, the alert system, the marketing campaign runner, a test file someone wrote in 2021 and never touched again
Now every time a new messaging channel is added, you will end up hunting through the codebase looking for the if-else blocks to update. That is quite scary, believe me.
Here comes, the Factory Pattern. You centralize the object creation logic.
Class NotificationFactory Static Method GetSender(notificationType) If notificationType == "Email" Return new EmailSender() Else if notificationType == "SMS" Return new SmsSender() Else if notificationType == "Push" Return new PushSender() Else Throw "Unsupported notification type"
Business logic will simply be,
sender = NotificationFactory.GetSender(type) sender.Send("Hello from the Factory Pattern!")
No if-else chaos. Easy to test just the factory. Add new types in one place and not all over the codebase.
3. From “Notify Everyone Manually” to Observer Pattern
The Problem:
You are building a blog posting platform. In your code, once a blog is published, you manually call,
SendEmail(post) SendSlackMessage(post) SendPushNotification(post) UpdateDashboard(post)
Looks fine. Until,
Product: "Can we also notify Telegram users?"
Marketing: "Add WhatsApp Business too!"
Manager: "Hey, can we print it out for our non-tech team?"
Now we have the Observer Pattern to our rescue. The idea is to let other parts of the system subscribe to an event, and get notified when that event occurs, without the publisher knowing who they are.
Class BlogPublisher subscribers = [] Method Subscribe(handler) subscribers.Add(handler) Method Publish(post) For each handler in subscribers handler.Update(post)
Usage,
publisher = new BlogPublisher() publisher.Subscribe(SendEmail) publisher.Subscribe(SendSlack) publisher.Subscribe(UpdateDashboard) publisher.Publish("New blog: Design Patterns for Devs")
Now you can add or remove subscribers without touching the Publish logic. Zero coupling.
4. From “Let Me Add One More Flag” to Decorator Pattern
The Problem:
You are building a basic messaging system. But now business/stakeholders want to have,
Logging, Timestamps, Encryption, Retry on failure, ....
So you end up with a method something like: SendMessageWithLoggingAndTimestampAndEncryptionAndGlitter(message)
Or even worse… a jungle of Boolean flags:
SendMessage(message, log=true, encrypt=true, timestamp=true, glitter=false)
You have written the same send function 8 times with 12 combinations at different places in the code. One wrong combo, and its a disaster waiting to happen.
Comes into the picture, the Decorator Pattern. Instead of rewriting logic, wrap functionality around the core class, like Lego blocks.
Interface Notifier Method Send(message) Class BasicNotifier Implements Notifier Method Send → Just send the message Class TimestampDecorator Implements Notifier Constructor(notifier) Method Send(message) Add timestamp notifier.Send(updated message) Class LoggingDecorator Implements Notifier Constructor(notifier) Method Send(message) Log the message notifier.Send(message)
And then stack them as needed,
notifier = new LoggingDecorator( new TimestampDecorator( new BasicNotifier() ) ) notifier.Send("What a beautiful sunny day..")
So, Have you been using these? High chances are, YES!
You just didn’t know they were called:
- Strategy
- Factory
- Observer
- Decorator
The moment you recognize these patterns, you can better explain your experience in interviews, make smarter architecture choices and feel more confident next time someone says “design patterns”.
This post is an intro to a series on each of the most commonly used design patterns. I am sure, it will make you more confident, when someone talks about design patterns in your next tech interview. Hope you liked it, and, lets go straight to learn more about the Factory Pattern and Its Clones next.
Top comments (0)