System Design
Object-Oriented Design
Stack Overflow

Design Example: Stack Overflow

Stack Overflow is a community-driven Q&A platform that relies on a complex reputation system, user-generated content, and a robust notification engine.


Step 1: Requirements Gathering

Core Use Cases:

  • Questions: Users can post questions with tags.
  • Answers: Users can provide answers to questions.
  • Voting: Users can upvote or downvote questions and answers.
  • Reputation: Users gain or lose reputation based on community interactions.
  • Comments: Users can add comments to questions or answers.
  • Bounties: Users can offer reputation points to reward high-quality answers.
  • Moderation: High-reputation users can flag or close questions.

Reputation Rules:

  • Answer accepted: +15
  • Question upvoted: +10
  • Answer upvoted: +10
  • Question/Answer downvoted: -2

Step 2: Identify Core Objects

  • User: Represents a community member with a reputation score.
  • Question: The main content piece containing text and tags.
  • Answer: A response to a specific question.
  • Comment: A short text piece attached to a question or answer.
  • Vote: Records a user's upvote/downvote action.
  • Badge: A reward for specific achievements (e.g., "Great Answer").
  • Notification: Alerts users about new answers or comments.

Step 3: Design Class Diagram


Step 4: Implementation in TypeScript

enum QuestionStatus { OPEN, CLOSED, BOUNTY, DELETED }
 
class User {
  private reputation: number = 0;
 
  constructor(public id: string, public name: string) {}
 
  public updateReputation(delta: number) {
    this.reputation += delta;
  }
}
 
class Question {
  private answers: Answer[] = [];
  private comments: Comment[] = [];
  private votes: Vote[] = [];
 
  constructor(
    public id: string,
    public creator: User,
    public title: string,
    public content: string
  ) {}
 
  public addAnswer(answer: Answer) {
    this.answers.push(answer);
  }
}
 
class Vote {
  constructor(public userId: string, public value: number) {}
}

Deep Dive: Observer Pattern for Notifications

When a question is answered, the original poster and anyone following the question should be notified.

interface Observer {
  update(message: string): void;
}
 
class UserObserver implements Observer {
  constructor(private user: User) {}
  update(message: string) {
    console.log(`Notification for ${this.user.name}: ${message}`);
  }
}
 
class NotificationSystem {
  private observers: Map<string, Observer[]> = new Map();
 
  public subscribe(questionId: string, observer: Observer) {
    const list = this.observers.get(questionId) || [];
    list.push(observer);
    this.observers.set(questionId, list);
  }
 
  public notify(questionId: string, message: string) {
    this.observers.get(questionId)?.forEach(obs => obs.update(message));
  }
}

Wrap Up

Designing Stack Overflow is a lesson in State and Integrity. The reputation system must be deterministic, and the relationship between content (Questions, Answers, Comments) requires careful structuring to allow for efficient searching and notification delivery.

[!TIP] Use a Search Strategy pattern to allow switching between simple text search and complex tag-based filtering.