Design a Social Network (Facebook)
OOP design for a social network covering user profiles, friend connections with graph modeling, news feed generation, post creation with privacy controls, and notification systems.
The Problem
Your company's internal social platform serves 50,000 employees across 12 offices. The current system stores friend connections in a single relationships table with two user ID columns, and rebuilds each user's news feed from scratch on every page load by scanning every post from every friend. At peak hours (Monday morning, 9 AM across all time zones), the feed endpoint takes 30 seconds to respond because it joins posts, comments, likes, and privacy filters in a single query. Last week, a privacy bug exposed private posts to non-friends because the visibility check lived in the UI layer, not the domain model.
Social networks are deceptively complex because they blend graph theory with content aggregation and fine-grained access control. The friend graph is bidirectional (if Alice is friends with Bob, Bob is friends with Alice), friend requests have a lifecycle (pending, accepted, rejected), and every post has privacy rules that determine who can see it. A system that gets privacy wrong violates user trust. A system that gets feed generation wrong either shows stale content or melts under load.
Design the core classes for a Facebook-style social network that handles user profiles, friend connections with request lifecycle, post creation with privacy controls, a news feed with configurable ranking, likes and comments, and a notification system.
Requirements
Clarifying Questions
Before jumping into class design, ask questions to nail down the scope. Cover four areas: core actions, error handling, boundaries, and future extensions.
You: "What are the main actions a user can take? Create a profile, send friend requests, create posts, like, comment, and view a news feed?"
Interviewer: "Yes. Users create profiles with a name, bio, and profile picture URL. They send friend requests that can be accepted or rejected. They create posts with text content and optional images. They like and comment on posts from friends. And they view a personalized news feed."
Six core actions: profile management, friend requests, post creation, likes, comments, and feed viewing. Each action needs different validation rules. The friend request lifecycle immediately suggests a state machine. The feed requires aggregating posts from all friends.
You: "How does the friend request lifecycle work? Can users cancel pending requests or block other users?"
Interviewer: "A user sends a request, and the receiver can accept or reject it. The sender can cancel a pending request. Blocking is a follow-up, not core. Once friends, either user can unfriend the other."
Four transitions: send, accept, reject, cancel. Plus an unfriend action on established connections. We need to track the state of each request and the resulting friendship graph.
You: "What privacy levels exist for posts? Who decides visibility?"
Interviewer: "Three levels: PUBLIC (anyone can see), FRIENDS_ONLY (only friends of the author), and PRIVATE (only the author). The post author sets the level at creation time. Default is FRIENDS_ONLY."
Three visibility levels, set per post. The privacy check must happen at the domain level, not the UI. This is a core invariant: no one should see a post they lack permission for. We need a method like canView(viewer, post) that encapsulates this logic.
You: "How should the news feed work? Just chronological, or some kind of ranking?"
Interviewer: "The feed collects posts from all friends that the viewer is allowed to see. By default, sort by recency. But we should be able to swap in different ranking strategies: chronological, relevance-based (posts with more engagement first), or engagement-weighted (balancing recency and likes/comments)."
Multiple ranking strategies with the same input and output. Classic Strategy pattern. The feed aggregator pulls visible posts from friends, then delegates sorting to a pluggable strategy.
You: "Can users like both posts and comments? Can they like something more than once?"
Interviewer: "Users can like posts and comments. One like per user per target. Liking the same thing again is a no-op. Users can also unlike."
Idempotent likes on two different target types (posts and comments). We need to prevent duplicates, which means tracking who liked what. A Set of user IDs per likeable entity works well.
You: "What triggers notifications? How are they delivered?"
Interviewer: "Notify a user when: someone sends them a friend request, someone accepts their friend request, someone likes their post, and someone comments on their post. Delivery mechanism is out of scope, just model the notification creation."
Four notification triggers, all following the same pattern: an action happens, and the relevant user gets notified. This is the Observer pattern: the notification system observes events from the social network and creates notifications.
You: "Should we support groups, stories, share/repost, or message threads?"
Interviewer: "Those are extensions. Focus on profiles, friends, posts with privacy, feed, likes, comments, and notifications. We can discuss groups and stories as follow-ups."
Good. You have clarified the core scope and pushed groups, stories, messaging, and sharing into extensions.
Final Requirements
Functional Requirements:
- Users create and update profiles (name, bio, profile picture URL)
- Users send, accept, reject, and cancel friend requests; unfriend existing friends
- Users create posts with text content, optional image URL, and a privacy level (PUBLIC, FRIENDS_ONLY, PRIVATE)
- Users like and unlike posts and comments (one like per user per target, idempotent)
- Users comment on posts (flat comment list per post)
- News feed aggregates visible posts from friends, sorted by a configurable ranking strategy
- Notifications created on: friend request received, friend request accepted, post liked, post commented on
Non-Functional Requirements:
- Thread safety for concurrent likes on the same post
- Extensibility for new post types, ranking strategies, and notification channels
- O(1) duplicate-like prevention per user per target
Out of Scope:
- UI rendering and image storage
- Persistence and database layer
- Groups, stories, messaging, share/repost (discussed as extensions)
- Notification delivery (email, push); only notification creation
Example Inputs and Outputs
Scenario 1: Friend Request Lifecycle
- User Alice sends a friend request to Bob
- Bob accepts the request
- Expected: Alice and Bob appear in each other's friend lists. Both receive notifications (Alice: "Bob accepted your request"; Bob: "Alice sent you a request" at send time).
Scenario 2: Post with Privacy
- Alice creates a FRIENDS_ONLY post: "Excited about the new project!"
- Bob (Alice's friend) views his feed and sees the post
- Charlie (not Alice's friend) views his feed and does NOT see the post
- Expected: Privacy filter correctly gates visibility based on friendship status.
Scenario 3: Feed Ranking
- Bob has three friends: Alice, Charlie, and Diana
- Alice posted 1 hour ago (2 likes), Charlie posted 5 minutes ago (0 likes), Diana posted 30 minutes ago (10 likes)
- With chronological ranking: Charlie's post, Diana's post, Alice's post
- With engagement ranking: Diana's post (10 likes), Alice's post (2 likes), Charlie's post (0 likes)
- Expected: Same posts, different order based on the active ranking strategy.
Try It Yourself
Try it yourself
Before reading the solution, spend 20 minutes sketching your class diagram. Focus on three things: how you model the bidirectional friend graph, how privacy filtering works at the domain level (not UI), and how you would swap ranking strategies for the feed. Compare your approach with the walkthrough below.
Step 1: Identify Core Entities
Start by asking: what are the main "things" in this problem? Look for nouns in your requirements. Each noun that has its own lifecycle or distinct responsibility becomes a candidate entity.
A common mistake in social network design is cramming everything into a single User class: friends, posts, feed logic, notifications, privacy checks. That produces a god class with 30 methods. Good design means each class has a single, clear job.
| Entity | Responsibility | Key attributes |
|---|---|---|
| SocialNetwork | The orchestrator. Manages users, processes friend requests, delegates feed generation. | users, friendRequests, feedService |
| User | Identity and profile data. Owns their posts and friend list. | userId, profile, friends, posts |
| Profile | Value object holding display info. Separates identity from presentation. | name, bio, profilePictureUrl |
| FriendRequest | Tracks the lifecycle of a connection request. Owns its own state machine. | sender, receiver, status, createdAt |
| Post | Content unit with privacy. Knows who created it and who can see it. | postId, author, content, imageUrl, privacy, likes, comments, createdAt |
| Comment | Text attached to a post. Likeable just like posts. | commentId, author, content, likes, createdAt |
| Like | Value object recording who liked what and when. | userId, createdAt |
| NewsFeed | Aggregates and ranks visible posts for a user. Delegates ranking to a strategy. | posts |
| Notification | Immutable record of an event a user should see. | notificationId, recipient, message, type, createdAt, read |
Notice we separated Profile from User because profile data (name, bio, picture) changes independently from identity and authentication data. Merging them violates SRP once you add profile editing, privacy settings, and account management as separate concerns.
I find that separating the friend graph from the feed is the design decision that impresses interviewers most. The friend graph answers "who is connected to whom." The feed answers "what should I show this user right now." Those are fundamentally different questions with different performance characteristics.
Step 2: Define Relationships and Class Design
Class Diagram
Deriving the Core Classes
SocialNetwork (Orchestrator)
Continue Reading with Premium
Unlock this article and every other in-depth system design guide on the platform with NotesFromSDE Premium.