Phase 1: Requirements & Use Cases
Interviewer: "Design a pub/sub messaging system."
Candidate: "Let me confirm scope. We're building an in-process publish-subscribe system — a message bus where publishers emit events to named topics, and multiple subscribers receive each event independently. This is NOT a distributed message broker like Kafka or RabbitMQ; we're designing the OOD model within a single process. Does that match?"
Interviewer: "Yes. What actors and use cases are you targeting?"
Candidate: "The actors are Publishers (emit events), Subscribers (receive events), and an Event Bus / Broker (routes messages). The core use cases are:
subscribe(topic, handler)— a subscriber registers interest in a topic with a callbackunsubscribe(topic, subscriber)— remove a subscriber from a topicpublish(topic, event)— a publisher broadcasts an event to all subscribers of a topiccreate_topic(name)— register a new topiclist_topics()— enumerate available topics- Async delivery — published events are delivered asynchronously so the publisher doesn't block on slow subscribers"
Interviewer: "What about guaranteed delivery? What happens if a subscriber is slow or throws an exception?"
Candidate: "I'll design for best-effort delivery in V1 — if a subscriber's handler throws, we log and continue to the next subscriber. The publisher always returns after submitting the event to the bus; delivery happens on a thread pool. I'll note where durable delivery (acking, dead-letter queues) would plug in as a V2 extension."
WHY: Guaranteed delivery requires persisting events and tracking per-subscriber acknowledgements — that's a significant scope increase. Best-effort covers the dominant…
In the full tutorial
- Phase 2: Object Modeling
- Phase 3: Class Design & Relationships
- Phase 4: Design Patterns Application
- Phase 5: Key Implementation
- Phase 6: Extensibility & Trade-offs