đź“…Week-2 (Day 2) -Real-World LLD: Building a Document Editor Inspired by Google Docs

Payal KumariPayal Kumari
7 min read

NOTE: - I started my 8-week system design journey with Coder Army. I will be journaling every day, recording what I learn, reflecting on it, and sharing it with my network to help newcomers to system design.

đź’  What are we building? A design similar to Google Docs.

  • Imagine you're writing a document online (like Google Docs). You type text 📝, add images 🖼️, save the file đź’ľ, and maybe preview it đź‘€.
    Behind the scenes, a lot of components are working together!

(Hindi: Sochiye aap ek online document likh rahe hain, jisme aap likh rahe hain, image daal rahe hain, save kar rahe hain — in sab ke peeche ek strong system bana hota hai jo yeh sab handle karta hai.)

📍Concepts Covered

  • âś… Classes & Relationships

  • âś… SOLID-compliant structure

  • âś… Extensibility & Modularity

(Hindi: Aaj hum seekhenge ki kaise alag-alag classes milke ek poora system banati hain, aur kaise hum ise flexible aur future-ready bana sakte hain.)

📍 Real-Life Analogy

Let’s say you're writing a recipe book .

  • TextElement = Ingredients ya steps jo aap likh rahe hain

  • ImageElement = Khana ka photo

  • Document = Pura recipe book

  • DocumentEditor = Aap, jo likh rahe hain

  • DocumentRenderer = Print karne wali machine ya screen view

  • FileStorage/DBStorage = Notebook ya Google Drive jahan aap save karte ho

(Hindi: Ye example humare design ko asaan aur relatable banata hai.)

📍System Design Overview (LLD)

Let’s understand the key components 👇

1) DocumentElement (Abstract Class)

Acts as a blueprint for elements like text and images.

(Hindi: Ye ek aisi class hai jisko use karke hum text aur image jaisa content define karte hain.)

abstract class DocumentElement {
    public abstract void render();
}

➡️ Subclasses: TextElement & ImageElement
(Hindi: In dono classes se hume pata chalta hai ki humara content kya hoga — text ya image.)

class TextElement extends DocumentElement {
    void render() { /* display text */ }
}

class ImageElement extends DocumentElement {
    void render() { /* display image */ }
}

2) Document Class

It stores multiple elements like paragraphs and images.

(Hindi: Ye pura document represent karta hai jisme hum alag-alag content add karte hain.)

class Document {
    List<DocumentElement> elements = new ArrayList<>();

    void addElement(DocumentElement el) {
        elements.add(el);
    }

    List<DocumentElement> getElements() {
        return elements;
    }
}

3) Persistence (Abstract Class)

Saves data to file/database
(Hindi: Ye class document save karne ka kaam karti hai)

📍Implementations:

  • FileStorage ➡️ Local save

  • DBStorage ➡️ Cloud save

abstract class Persistence {
    abstract void save(String data);
}

class FileStorage extends Persistence {
    void save(String data) { /* save to file */ }
}

class DBStorage extends Persistence {
    void save(String data) { /* save to DB */ }
}

4) DocumentEditor

Used to add text or image and save the document.

(Hindi: Ye editor user ke liye hai jahan se woh document me text ya image add kar sakta hai.)

class DocumentEditor {
    Document doc = new Document();

    void addText(String text) {
        doc.addElement(new TextElement());
    }

    void addImage(String path) {
        doc.addElement(new ImageElement());
    }
}

5) DocumentRenderer

Used to render/display the document on screen or paper.

(Hindi: Iska kaam document ko screen ya printer pe dikhana hai.)

class DocumentRenderer {
    void render(Document doc) {
        for (DocumentElement el : doc.getElements()) {
            el.render();
        }
    }
}

📍 Relationships Between Classes

  • Document contains multiple DocumentElements (Composition)
    (Hindi: Document ke andar kai content elements hote hain.)

  • DocumentEditor uses Document and Persistence to save and update
    (Hindi: Editor document me changes karta hai aur usse save karta hai.)

  • TextElement & ImageElement inherit from DocumentElement
    (Hindi: Ye dono classes ek common base se aati hain — isse code reuse hota hai.)

đź’ SOLID Principles at Work

PrincipleHow it's UsedHindi Explanation
S - Single ResponsibilityEach class does one thing onlyHar class ka ek hi kaam hai
O - Open/ClosedEasy to extend with new elementsNaye features easily add ho sakte hain
L - Liskov SubstitutionSubclasses can replace base classSubclasses ko base ki jagah use kar sakte ho
I - Interface SegregationSmall, focused interfacesSirf jarurat ke methods
D - Dependency InversionDepends on abstractionHigh-level modules abstractions pe depend karte hain

đź’ Extensibility & Modularity

  • Want to support videos in the future? Add a VideoElement.
    (Hindi: Future me video support chahiye? Ek nayi class banao aur kaam ho gaya!)

  • Want to save to cloud? Add a CloudStorage class.
    (Hindi: Cloud me save karna hai? Nayi class likho aur bas!)

đź’ Final Thoughts

Designing a Google Docs-like editor helped me understand how real-world applications work from the inside.

(Hindi: Is project se mujhe samajh aaya ki bade applications jaise Google Docs kaise internally kaam karte hain.)

Everything is built in parts — and every part is reusable, replaceable, and extendable

Flowchart diagram illustrating a document processing system with components like DocumentElement, Document, and Persistence. Shows relationships, methods like render(), save(), and entities like TextElement and ImageElement.

import java.util.ArrayList;
import java.util.List;
import java.io.FileWriter;
import java.io.IOException;

// Interface for document elements
interface DocumentElement {
    public abstract String render();
}

// Concrete implementation for text elements
class TextElement implements DocumentElement {
    private String text;

    public TextElement(String text) {
        this.text = text;
    }

    @Override
    public String render() {
        return text;
    }
}

// Concrete implementation for image elements
class ImageElement implements DocumentElement {
    private String imagePath;

    public ImageElement(String imagePath) {
        this.imagePath = imagePath;
    }

    @Override
    public String render() {
        return "[Image: " + imagePath + "]";
    }
}

// NewLineElement represents a line break in the document.
class NewLineElement implements DocumentElement {
    @Override
    public String render() {
        return "\n";
    }
}

// TabSpaceElement represents a tab space in the document.
class TabSpaceElement implements DocumentElement {
    @Override
    public String render() {
        return "\t";
    }
}

// Document class responsible for holding a collection of elements
class Document {
    private List<DocumentElement> documentElements = new ArrayList<>();

    public void addElement(DocumentElement element) {
        documentElements.add(element);
    }

    // Renders the document by concatenating the render output of all elements.
    public String render() {
        StringBuilder result = new StringBuilder();
        for (DocumentElement element : documentElements) {
            result.append(element.render());
        }
        return result.toString();
    }
}

// Persistence Interface
interface Persistence {
    void save(String data);
}

// FileStorage implementation of Persistence
class FileStorage implements Persistence {
    @Override
    public void save(String data) {
        try {
            FileWriter outFile = new FileWriter("document.txt");
            outFile.write(data);
            outFile.close();
            System.out.println("Document saved to document.txt");
        } catch (IOException e) {
            System.out.println("Error: Unable to open file for writing.");
        }
    }
}

// Placeholder DBStorage implementation
class DBStorage implements Persistence {
    @Override
    public void save(String data) {
        // Save to DB
    }
}

// DocumentEditor class managing client interactions
class DocumentEditor {
    private Document document;
    private Persistence storage;
    private String renderedDocument = "";

    public DocumentEditor(Document document, Persistence storage) {
        this.document = document;
        this.storage = storage;
    }

    public void addText(String text) {
        document.addElement(new TextElement(text));
    }

    public void addImage(String imagePath) {
        document.addElement(new ImageElement(imagePath));
    }

    // Adds a new line to the document.
    public void addNewLine() {
        document.addElement(new NewLineElement());
    }

    // Adds a tab space to the document.
    public void addTabSpace() {
        document.addElement(new TabSpaceElement());
    }

    public String renderDocument() {
        if (renderedDocument.isEmpty()) {
            renderedDocument = document.render();
        }
        return renderedDocument;
    }

    public void saveDocument() {
        storage.save(renderDocument());
    }
}

// Client usage example
public class DocumentEditorClient {
    public static void main(String[] args) {
        Document document = new Document();
        Persistence persistence = new FileStorage();

        DocumentEditor editor = new DocumentEditor(document, persistence);

        // Simulate a client using the editor with common text formatting features.
        editor.addText("Hello, world!");
        editor.addNewLine();
        editor.addText("This is a real-world document editor example.");
        editor.addNewLine();
        editor.addTabSpace();
        editor.addText("Indented text after a tab space.");
        editor.addNewLine();
        editor.addImage("picture.jpg");

        // Render and display the final document.
        System.out.println(editor.renderDocument());

        editor.saveDocument();
    }
}

Week - 2 (Day 2) Completed âś… System Design

NOTE : - A big thanks to my mentors Rohit Negi Sir and Aditya Sir for launching this amazing 8-week course absolutely free on YouTube via CoderArmy9 :- youtube.com/@CoderArmy9 . 🙌

👉 Share this blog with your connections! Let’s keep learning, growing, and supporting one another on this journey. 🚀

✍️ Payal Kumari 👩‍💻 Github

Jai Hind 🇮🇳 | #CoderArmy #LearningInPublic #SystemDesign #TechForAll #MentorshipMatters #8weeksLLdChallenge #LowLevelDesign #Code #LLD #OOP

0
Subscribe to my newsletter

Read articles from Payal Kumari directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Payal Kumari
Payal Kumari

I'm a passionate full-stack developer with a strong foundation in the MERN stack—building and maintaining scalable web applications using React.js, Node.js, and Next.js. My journey in open source began with Hacktoberfest 2023, where I made four impactful pull requests that sparked a love for collaborative coding, global learning, and open knowledge sharing. Since then, I’ve contributed to and mentored projects in top open source programs like GSSoC’24, SSOC’24, and C4GT’24. As a Google Gen AI Exchange Hackathon ’24 Finalist and Google’s Women Techmakers (WTM) Ambassador, I’ve been privileged to support diverse communities in building meaningful tech solutions. My work as a Top 50 Mentor for GSSoC ’24 reflects my commitment to nurturing new talent in tech. Beyond development, I serve as a Student Career Guide, Profile Building Expert & Evangelist at Topmate.io, where I conduct workshops, guide students through resume building and career strategy, and help mentees navigate open source and tech careers. Recognized among the Top 5% of mentors and featured on “Topmate Discover,” I take pride in making mentorship accessible and impactful. My technical voice has also been acknowledged by LinkedIn, where I’ve earned the Top Voice badge seven times in domains like web development, programming, and software engineering. In addition, I hold LinkedIn Golden Badges for Research Skills, Interpersonal Skills, Critical Thinking, and Teamwork—signaling a well-rounded approach to both individual contribution and team collaboration. Graduating with an MCA from Chandigarh University in 2023, I’ve continued to fuel my curiosity by writing technical articles and sharing practical MERN stack insights across platforms. Whether it’s building polished UIs, optimizing backend performance, or guiding a mentee through their first pull request, I’m driven by the power of community and continuous learning. Let’s connect! I'm open to collaborations, mentorship, or building something impactful together. Reach out to me at kumaripayal7488@gmail.com or visit my profile on Topmate.io.