Concurrency / Realtime• Patterns: Command, Observer, Strategy
Google Docs
Hard
Problem Summary
Design a real-time Collaborative Rich-Text Document Editor supporting concurrent multi-user editing, Operational Transformation (OT) conflict resolution, and version history snapshots.
Functional Scope
- Concurrent document modifications by multiple remote collaborators.
- Operational Transformation (OT) or CRDT strategy to guarantee eventual consistency.
- Command pattern encapsulating document mutations (Insert, Delete, Format).
- Observer pattern broadcasting transformed operations to connected WebSocket peers.
- Monotonically increasing document revisions and snapshot recovery.
Entity-Relationship (ER) Schema
Document [1] --> [*] Operation Document [1] --> [1] ConflictResolverStrategy Document [1] --> [*] CollaboratorObserver
Design Approach
Apply the Command pattern for editing operations and Strategy for Operational Transformation (OT) transformation matrices, ensuring all collaborators converge on identical document contents.
Core Classes & Models
Document (DocId, revision, text buffer)Operation (Type: INSERT, DELETE, position, text content, authorId, clientRevision)ConflictResolverStrategy (OperationalTransformationStrategy, CRDTStrategy)CollaboratorObserver (Broadcasts transformed operations to connected peers)HistoryManager (Snapshot creation and revision rollback)
Code Blueprint
89 lines/**
* Low-Level Design: Google Docs Collaborative Text Editor
* Design Patterns Applied:
* - Command Pattern: Encapsulating keystrokes, inserts, deletes with Undo / Redo support
* - Observer Pattern: Real-time broadcast of document edits to active collaborators
* - Strategy Pattern: Operational Transformation (OT) conflict resolution strategies
*/
import java.util.*;
// --- [DESIGN PATTERN: Observer] Real-time collaborator sync ---
interface DocumentObserver {
void onDocumentModified(int version, String fullText);
}
class CollaboratorView implements DocumentObserver {
private final String userId;
public CollaboratorView(String userId) { this.userId = userId; }
@Override
public void onDocumentModified(int version, String fullText) {
System.out.printf("💻 [Collaborator %s] Sync v%d: \"%s\"%n", userId, version, fullText);
}
}
// --- [DESIGN PATTERN: Command] Text editing command with undo ---
interface EditorCommand {
void execute();
void undo();
}
class InsertTextCommand implements EditorCommand {
private final StringBuilder doc;
private final int index;
private final String text;
public InsertTextCommand(StringBuilder doc, int index, String text) {
this.doc = doc; this.index = index; this.text = text;
}
@Override
public void execute() {
doc.insert(index, text);
}
@Override
public void undo() {
doc.delete(index, index + text.length());
}
}
class CollaborativeDocument {
private final StringBuilder content = new StringBuilder();
private int version = 0;
private final Stack<EditorCommand> history = new Stack<>();
private final List<DocumentObserver> observers = new ArrayList<>();
public void addObserver(DocumentObserver o) { observers.add(o); }
public synchronized void applyCommand(EditorCommand cmd) {
cmd.execute();
history.push(cmd);
version++;
for (DocumentObserver o : observers) o.onDocumentModified(version, content.toString());
}
public synchronized void undo() {
if (!history.isEmpty()) {
EditorCommand cmd = history.pop();
cmd.undo();
version++;
for (DocumentObserver o : observers) o.onDocumentModified(version, content.toString());
}
}
public StringBuilder getContent() { return content; }
}
public class Main {
public static void main(String[] args) {
CollaborativeDocument doc = new CollaborativeDocument();
doc.addObserver(new CollaboratorView("Alice"));
doc.addObserver(new CollaboratorView("Bob"));
System.out.println("--- Collaborative Editing ---");
doc.applyCommand(new InsertTextCommand(doc.getContent(), 0, "Hello "));
doc.applyCommand(new InsertTextCommand(doc.getContent(), 6, "World!"));
doc.undo();
}
}