Design patterns appear in coding interviews in two ways: the interviewer asks you to implement a specific pattern, or you’re expected to recognize that a pattern applies to the problem and mention it naturally. Knowing the six patterns below covers the vast majority of what comes up.
Strategy Pattern
Intent: Define a family of algorithms, encapsulate each one, and make them interchangeable. The client selects a strategy at runtime without knowing its implementation.
# Python
class Sorter:
def __init__(self, strategy):
self._strategy = strategy
def sort(self, data):
return self._strategy.sort(data)
class QuickSort:
def sort(self, data): ...
class MergeSort:
def sort(self, data): ...
sorter = Sorter(QuickSort())
sorter.sort([3, 1, 2])
When to use: multiple algorithms for the same behavior (sorting, pricing, routing); want to swap implementations at runtime or per-config without branching logic. Also appears as the payment processor pattern: PaymentStrategy with StripeStrategy and PayPalStrategy implementations.
Observer Pattern
Intent: Define a one-to-many dependency so that when one object changes state, all its dependents are notified automatically.
# Python
class EventBus:
def __init__(self):
self._subscribers = defaultdict(list)
def subscribe(self, event_type, handler):
self._subscribers[event_type].append(handler)
def publish(self, event_type, data):
for handler in self._subscribers[event_type]:
handler(data)
bus = EventBus()
bus.subscribe("price_change", send_alert_email)
bus.subscribe("price_change", update_dashboard)
bus.publish("price_change", {"ticker": "AAPL", "price": 189.50})
Push vs pull: in push mode the subject sends the new value to observers (shown above). In pull mode the subject sends a notification and observers fetch the data themselves — useful when observers only need a subset of the data. In system design interviews, Observer is the conceptual basis for event-driven architectures (Kafka topics, webhook callbacks, UI reactivity).
Factory Pattern
Factory Method: define an interface for creating an object, but let subclasses decide which class to instantiate.
# Java-style pseudocode
abstract class NotificationSender {
abstract Notification createNotification(String msg);
void send(String msg) {
Notification n = createNotification(msg);
n.deliver();
}
}
class EmailSender extends NotificationSender {
Notification createNotification(String msg) {
return new EmailNotification(msg);
}
}
Abstract Factory: creates families of related objects. Example: a UIFactory that produces Button, Checkbox, and Dialog — with a DarkThemeFactory and LightThemeFactory as concrete implementations. Use Abstract Factory when the products must be consistent with each other.
Singleton Pattern
Intent: Ensure a class has only one instance and provide a global access point to it.
# Python thread-safe (double-checked locking equivalent via module-level)
class ConfigManager:
_instance = None
_lock = threading.Lock()
@classmethod
def get_instance(cls):
if cls._instance is None:
with cls._lock:
if cls._instance is None: # second check inside lock
cls._instance = cls()
return cls._instance
When NOT to use: Singletons introduce hidden global state that makes unit testing hard — you can’t inject a mock. For most cases, create one instance at application startup and pass it via dependency injection instead. Mention this trade-off in interviews; it signals maturity.
Decorator Pattern
Intent: Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.
# Python — wrapping an HTTP client with logging and retry
class HttpClient:
def get(self, url): ...
class LoggingDecorator:
def __init__(self, client):
self._client = client
def get(self, url):
print(f"GET {url}")
response = self._client.get(url)
print(f"Response: {response.status}")
return response
class RetryDecorator:
def __init__(self, client, retries=3):
self._client = client
self._retries = retries
def get(self, url):
for attempt in range(self._retries):
try:
return self._client.get(url)
except Exception:
if attempt == self._retries - 1:
raise
client = RetryDecorator(LoggingDecorator(HttpClient()))
Java’s InputStream/BufferedInputStream/GZIPInputStream chain is the textbook example. In web frameworks, middleware stacks are a direct application of Decorator.
Command Pattern
Intent: Encapsulate a request as an object, thereby letting you parameterize clients, queue operations, log them, and support undoable operations.
class Command:
def execute(self): ...
def undo(self): ...
class InsertTextCommand(Command):
def __init__(self, doc, position, text):
self.doc = doc
self.position = position
self.text = text
def execute(self):
self.doc.insert(self.position, self.text)
def undo(self):
self.doc.delete(self.position, len(self.text))
class Editor:
def __init__(self):
self.history = []
def run(self, cmd):
cmd.execute()
self.history.append(cmd)
def undo(self):
if self.history:
self.history.pop().undo()
Command appears in system design when discussing collaborative document editors (like Google Docs): each keystroke is a Command object that can be applied, reversed, or transmitted to other clients for operational transform.
Patterns in System Design Interviews
- Strategy: mention when designing a dispatch system, ranking algorithm, or payment flow — “we can abstract the routing logic behind a Strategy interface so we can swap algorithms without touching the core service.”
- Observer: use when explaining event-driven architecture — “downstream services subscribe to order events via Kafka; this is the Observer pattern at the infrastructure level.”
- Command: invoke when discussing undo/redo (collaborative editors) or audit logs — “every mutation is a Command object persisted to an event log, which gives us replay and rollback for free.”
Meta coding interviews test OOP design and design patterns. See common questions for Meta interview: object-oriented design and design patterns.
Atlassian coding rounds include OOP design and design patterns. Review patterns for Atlassian interview: design patterns and OOP system design.
Apple coding interviews test design patterns and OOP principles. See patterns for Apple interview: design patterns and object-oriented design.