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.

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
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
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]
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]
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
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