problemhardood

Object-Oriented Design for Stack Overflow

Problem

Design an object-oriented system for an online Q&A community (similar to Stack Overflow) where developers ask and answer questions, vote, comment, tag, earn reputation and badges, place bounties, and moderators/admins manage community integrity.

Stack Overflow

Solution

1. Requirements Analysis

Functional Requirements:

  • Guest users can search and view questions; must register to ask, answer, comment, vote, or flag.
  • Members can post questions with tags and optional bounty; edit their own posts.
  • Members can add answers to open questions; question owners can accept an answer.
  • Members can comment on any question or answer.
  • Members can upvote or flag questions, answers, and comments.
  • Members can vote to close or delete certain questions (subject to thresholds); moderators can close, delete, or reopen any question.
  • Members can add bounties to their questions to draw attention (reputation and expiry tracked).
  • System assigns badges based on reputation/activity and identifies frequently used tags.
  • Tags associated with questions; track daily and weekly tag usage frequencies.
  • Moderators and admins manage member status (block/unblock) and content moderation.
  • Notifications are sent for events (badge awards, accepted answers, bounty expirations, moderator actions).

Non-Functional (inferred):

  • Scalability to large volume of questions, answers, tags, votes.
  • Integrity and auditability for moderation actions and reputation changes.
  • Extensibility for new badge types/rules.
  • Availability and responsiveness for search and voting operations.

2. Use Case Diagram

Actors: Guest, Member, Moderator, Admin, System.

Primary Use Cases: Search Questions, Post Question (with tags/bounty), Answer Question, Comment on Post, Vote/Flag Post, Close/Reopen Question (moderator), Delete/Undelete Question, Assign Badge (system), Manage Member Status (admin), Track Tag Frequencies.

graph TD
    subgraph QA[Q&A Platform]
        UC_Search(Search Questions)
        UC_Post(Post Question)
        UC_Answer(Add Answer)
        UC_Comment(Add Comment)
        UC_Vote(Vote/Flag Post)
        UC_Close(Close/Reopen Question)
        UC_Delete(Delete/Undelete Question)
        UC_Badge(Assign Badge)
        UC_TagFreq(Update Tag Frequencies)
        UC_Bounty(Add Bounty)
        UC_Manage(Block/Unblock Member)
    end
    Guest --> UC_Search
    Member --> UC_Search
    Member --> UC_Post
    Member --> UC_Answer
    Member --> UC_Comment
    Member --> UC_Vote
    Member --> UC_Bounty
    Moderator --> UC_Close
    Moderator --> UC_Delete
    Admin --> UC_Manage
    System --> UC_Badge
    System --> UC_TagFreq

Stack Overflow Use Case Diagram

3. Class Diagram

Core Classes & Responsibilities:

  • Question: Title, description, view/vote counts, status, closing remark, bounty, photos, answers, comments.
  • Answer: Text, vote/flag counts, acceptance status, photos.
  • Comment: Text, vote/flag counts, creation metadata.
  • Tag: Name, description, daily/weekly usage frequency tracking.
  • Badge: Name and description for achievements.
  • Bounty: Reputation amount and expiry to boost question visibility.
  • Photo: Image metadata associated with questions/answers.
  • Account (Guest, Member, Moderator, Admin): User identity, reputation, privileges.
  • Notification: Content and delivery for system events.
  • Search: Abstract base for search operations.
classDiagram
    class Question {
        +title: String
        +description: String
        +viewCount: int
        +voteCount: int
        +status: QuestionStatus
        +close()
        +undelete()
        +addComment()
        +addBounty()
    }
    class Answer {
        +text: String
        +voteCount: int
        +flagCount: int
        +accepted: boolean
        +incrementVoteCount()
    }
    class Comment {
        +text: String
        +voteCount: int
        +flagCount: int
        +incrementVoteCount()
    }
    class Tag { +name: String +description: String +dailyFreq: int +weeklyFreq: int }
    class Badge { +name: String +description: String }
    class Bounty { +reputation: int +expiry: Date +modifyReputation() }
    class Photo { +id: String +path: String +delete() }
    class Account { +id: String +status: AccountStatus +resetPassword() }
    class Member { +createQuestion() +createTag() }
    class Admin { +blockMember() +unblockMember() }
    class Moderator { +closeQuestion() +undeleteQuestion() }
    class Notification { +id: String +content: String +sendNotification() }
    class Search { +search(query) }
    Account <|-- Member
    Member <|-- Admin
    Member <|-- Moderator
    Question "1" -- "*" Answer : has
    Question "1" -- "*" Comment : has
    Question "1" -- "*" Tag : tagged
    Question "1" -- "0..1" Bounty : bounty
    Question "1" -- "*" Photo : media
    Answer "1" -- "*" Photo : media
    Member "1" -- "*" Badge : awards

Stack Overflow Class Diagram Stack Overflow UML

4. Activity Diagrams

Activity: Post New Question

graph TD
    Q1[Member clicks 'Ask Question'] --> Q2[Enter title & description]
    Q2 --> Q3[Add tags]
    Q3 --> Q4{Add bounty?}
    Q4 -- Yes --> Q5[Specify bounty & expiry]
    Q4 -- No --> Q6[Skip]
    Q5 --> Q7[Submit question]
    Q6 --> Q7[Submit question]
    Q7 --> Q8[System indexes question & updates tag freq]

Stack Overflow Activity Diagram

Activity: Answer a Question

graph TD
    A1[Member views question] --> A2[Read existing answers]
    A2 --> A3[Compose answer]
    A3 --> A4[Submit]
    A4 --> A5[System records answer]
    A5 --> A6[Question owner may accept later]

Activity: Voting on a Post

graph TD
    V1[Member opens post] --> V2{Has voted before?}
    V2 -- Yes --> V3[Prevent duplicate vote]
    V2 -- No --> V4[Register vote]
    V4 --> V5[Update reputation]

Stack Overflow Sequence Diagram

5. High-Level Code Implementation

Java

enum QuestionStatus { OPEN, CLOSED, ON_HOLD, DELETED }
enum QuestionClosingRemark { DUPLICATE, OFF_TOPIC, TOO_BROAD, NOT_CONSTRUCTIVE, NOT_A_REAL_QUESTION, PRIMARILY_OPINION_BASED }
enum AccountStatus { ACTIVE, CLOSED, CANCELED, BLACKLISTED, BLOCKED }

class Account {
    String id, password, name, address, email, phone; AccountStatus status; int reputation;
    void resetPassword() {}
}
class Member {
    Account account; java.util.List<Badge> badges; int getReputation() { return account.reputation; }
    void createQuestion(Question q) {}
    void createTag(Tag t) {}
}
class Admin extends Member { void blockMember(Member m) {} void unblockMember(Member m) {} }
class Moderator extends Member { void closeQuestion(Question q) {} void undeleteQuestion(Question q) {} }

class Badge { String name, description; }
class Tag { String name, description; int dailyFreq, weeklyFreq; }
class Bounty { int reputation; java.util.Date expiry; void modifyReputation(int rep) {} }
class Photo { String id, path, creationDate; Member creatingMember; void delete() {} }
class Notification { String id, content, createdOn; void sendNotification() {} }

abstract class Search { java.util.List<Question> search(String query) { return java.util.Collections.emptyList(); } }

class Question extends Search {
    String title, description; int viewCount, voteCount; java.util.Date creationTime, updateTime; QuestionStatus status; QuestionClosingRemark closingRemark; Bounty bounty; Member askingMember; java.util.List<Photo> photos; java.util.List<Comment> comments; java.util.List<Answer> answers;
    void close() {}
    void undelete() {}
    void addComment(Comment c) {}
    void addBounty(Bounty b) {}
    @Override public java.util.List<Question> search(String query) { return java.util.Collections.emptyList(); }
}
class Comment { String text; java.util.Date creationTime; int flagCount, voteCount; Member askingMember; void incrementVoteCount() {} }
class Answer { String text; boolean accepted; int voteCount, flagCount; java.util.Date creationTime; Member creatingMember; java.util.List<Photo> photos; void incrementVoteCount() {} }

Python

from enum import Enum
from datetime import datetime
from typing import List

class QuestionStatus(Enum):
    OPEN, CLOSED, ON_HOLD, DELETED = 1, 2, 3, 4

class QuestionClosingRemark(Enum):
    DUPLICATE, OFF_TOPIC, TOO_BROAD, NOT_CONSTRUCTIVE, NOT_A_REAL_QUESTION, PRIMARILY_OPINION_BASED = 1, 2, 3, 4, 5, 6

class AccountStatus(Enum):
    ACTIVE, CLOSED, CANCELED, BLACKLISTED, BLOCKED = 1, 2, 3, 4, 5

class Account:
    def __init__(self, id: str, password: str, name: str, address: str, email: str, phone: str, status: AccountStatus = AccountStatus.ACTIVE) -> None:
        self.__id = id; self.__password = password; self.__name = name; self.__address = address; self.__email = email; self.__phone = phone; self.__status = status; self.__reputation = 0
    def reset_password(self) -> None: pass

class Member:
    def __init__(self, account: Account) -> None:
        self.__account = account; self.__badges: List[Badge] = []
    def get_reputation(self) -> int: return self.__account._Account__reputation  # placeholder
    def get_email(self) -> str: return self.__account._Account__email
    def create_question(self, question: 'Question') -> None: pass
    def create_tag(self, tag: 'Tag') -> None: pass

class Admin(Member):
    def block_member(self, member: Member) -> None: pass
    def unblock_member(self, member: Member) -> None: pass

class Moderator(Member):
    def close_question(self, question: 'Question') -> None: pass
    def undelete_question(self, question: 'Question') -> None: pass

class Badge:
    def __init__(self, name: str, description: str) -> None:
        self.__name = name; self.__description = description

class Tag:
    def __init__(self, name: str, description: str) -> None:
        self.__name = name; self.__description = description; self.__daily_asked_frequency = 0; self.__weekly_asked_frequency = 0

class Notification:
    def __init__(self, id: str, content: str) -> None:
        self.__notification_id = id; self.__created_on = datetime.now(); self.__content = content
    def send_notification(self) -> None: pass

class Photo:
    def __init__(self, id: str, path: str, member: Member) -> None:
        self.__photo_id = id; self.__photo_path = path; self.__creation_date = datetime.now(); self.__creating_member = member
    def delete(self) -> None: pass

class Bounty:
    def __init__(self, reputation: int, expiry: datetime) -> None:
        self.__reputation = reputation; self.__expiry = expiry
    def modify_reputation(self, reputation: int) -> None: pass

class Search:
    def search(self, query: str) -> None: pass

class Question(Search):
    def __init__(self, title: str, description: str, bounty: Bounty, asking_member: Member) -> None:
        self.__title = title; self.__description = description; self.__view_count = 0; self.__vote_count = 0
        self.__creation_time = datetime.now(); self.__update_time = datetime.now(); self.__status = QuestionStatus.OPEN
        self.__closing_remark = QuestionClosingRemark.DUPLICATE; self.__bounty = bounty; self.__asking_member = asking_member
        self.__photos: List[Photo] = []; self.__comments: List[Comment] = []; self.__answers: List[Answer] = []
    def close(self) -> None: pass
    def undelete(self) -> None: pass
    def add_comment(self, comment: 'Comment') -> None: pass
    def add_bounty(self, bounty: Bounty) -> None: pass
    def search(self, query: str) -> None: pass

class Comment:
    def __init__(self, text: str, member: Member) -> None:
        self.__text = text; self.__creation_time = datetime.now(); self.__flag_count = 0; self.__vote_count = 0; self.__asking_member = member
    def increment_vote_count(self) -> None: pass

class Answer:
    def __init__(self, text: str, member: Member) -> None:
        self.__answer_text = text; self.__accepted = False; self.__vote_count = 0; self.__flag_count = 0; self.__creation_time = datetime.now(); self.__creating_member = member; self.__photos: List[Photo] = []
    def increment_vote_count(self) -> None: pass

Stack Overflow Sequence Diagram

Source https://github.com/tssovi/grokking-the-object-oriented-design-interview

from enum import Enum


class QuestionStatus(Enum):
    OPEN, CLOSED, ON_HOLD, DELETED = 1, 2, 3, 4


class QuestionClosingRemark(Enum):
    DUPLICATE, OFF_TOPIC, TOO_BROAD, NOT_CONSTRUCTIVE, NOT_A_REAL_QUESTION, PRIMARILY_OPINION_BASED = 1, 2, 3, 4, 5, 6


class AccountStatus(Enum):
    ACTIVE, CLOSED, CANCELED, BLACKLISTED, BLOCKED = 1, 2, 3, 4, 5


Account, Member, Admin, and Moderator: These classes represent the different people that interact with our system:

from .constants import *


# For simplicity, we are not defining getter and setter functions. The reader can
# assume that all class attributes are private and accessed through their respective
# public getter methods and modified only through their public methods function.


class Account:
    def __init__(self, id, password, name, address, email, phone, status=AccountStatus.Active):
        self.__id = id
        self.__password = password
        self.__name = name
        self.__address = address
        self.__email = email
        self.__phone = phone
        self.__status = status
        self.__reputation = 0

    def reset_password(self):
        None


class Member:
    def __init__(self, account):
        self.__account = account
        self.__badges = []

    def get_reputation(self):
        return self.__account.get_reputation()

    def get_email(self):
        return self.__account.get_email()

    def create_question(self, question):
        None

    def create_tag(self, tag):
        None


class Admin(Member):
    def block_member(self, member):
        None

    def unblock_member(self, member):
        None


class Moderator(Member):
    def close_question(self, question):
        None

    def undelete_question(self, question):
        None


Badge, Tag, and Notification: Members have badges, questions have tags and notifications:

from datetime import datetime


class Badge:
    def __init__(self, name, description):
        self.__name = name
        self.__description = description


class Tag:
    def __init__(self, name, description):
        self.__name = name
        self.__description = description
        self.__daily_asked_frequency = 0
        self.__weekly_asked_frequency = 0


class Notification:
    def __init__(self, id, content):
        self.__notification_id = id
        self.__created_on = datetime.datetime.now()
        self.__content = content
    
    def send_notification(self):
        None


Photo and Bounty: Members can put bounties on questions. Answers and Questions can have multiple photos:

from datetime import datetime

class Photo:
    def __init__(self, id, path, member):
        self.__photo_id = id
        self.__photo_path = path
        self.__creation_date = datetime.now()
        self.__creating_member = member
    
    def delete(self):
        None


class Bounty:
    def __init__(self, reputation, expiry):
        self.__reputation = reputation
        self.__expiry = expiry
    
    def modify_reputation(self, reputation):
        None


Question, Comment and Answer: Members can ask questions, as well as add an answer to any question. All members can add comments to all open questions or answers:

from datetime import datetime
from abc import ABC
from .constants import *

class Search(ABC):
    def search(self, query):
        None


class Question(Search):
    def __init__(self, title, description, bounty, asking_member):
        self.__title = title
        self.__description = description
        self.__view_count = 0
        self.__vote_count = 0
        self.__creation_time = datetime.now()
        self.__update_time = datetime.now()
        self.__status = QuestionStatus.OPEN
        self.__closing_remark = QuestionClosingRemark.DUPLICATE

        self.__bounty = bounty
        self.__asking_member = asking_member
        self.__photos = []
        self.__comments = []
        self.__answers = []

    def close(self):
        None

    def undelete(self):
        None

    def add_comment(self, comment):
        None

    def add_bounty(self, bounty):
        None

    def search(self, query):
        # return all questions containing the string query in their title or description.
        None


class Comment:
    def __init__(self, text, member):
        self.__text = text
        self.__creation_time = datetime.now()
        self.__flag_count = 0
        self.__vote_count = 0
        self.__asking_member = member

    def increment_vote_count(self):
        None


class Answer:
    def __init__(self, text, member):
        self.__answer_text = text
        self.__accepted = False
        self.__vote_count = 0
        self.__flag_count = 0
        self.__creation_time = datetime.now()
        self.__creating_member = member
        self.__photos = []

    def increment_vote_count(self):
        None


Source https://github.com/tssovi/grokking-the-object-oriented-design-interview

Comments