Design a Library Management System
In a 45-minute LLD interview, the key architectural themes are domain modeling separation (the conceptual book title vs physical inventory copies), Dependency Inversion Principle (DIP) (injecting persistence and fine policy abstractions into LibraryService), and Observer-based event dispatching (notifying patrons on reservation fulfillment). Scope the solution to catalog management, loan tracking, overdue fine computation, FIFO hold queues, and observer notifications. Mention hold expiration timers (48-hour pickup window) and member borrowing limits as extensions.
Problem statement & clarifying requirements
Design a Library Management System that manages catalog titles, physical barcoded book copies, member borrowing, hold reservations, and overdue fine calculations. The service layer must strictly adhere to the Dependency Inversion Principle (DIP) so that catalog persistence and fine calculation rules are injected as interfaces rather than hardcoded. When an overdue book is returned, the next member in the hold queue must be automatically alerted via the Observer pattern.
A BookTitle represents the intellectual work (ISBN, title, author, reservation hold queue), while a BookCopy represents a tangible inventory item with a unique barcode, rack location, and loan status.
Members join a FIFO hold queue attached to the BookTitle. When any copy of that ISBN is returned, it is immediately reserved for the next patron in line.
No. A copy with status Reserved can only be checked out by the member whose hold was fulfilled.
LibraryService depends exclusively on the CatalogRepository and FineCalculator abstract interfaces injected via constructor.
First, sketch the design yourself
Spend 5 minutes listing the classes, who owns whom, and which interface hides the part that changes.
- 1.
Differentiate conceptual works from physical inventory: Modeling a book as a single class with both an ISBN and a single loan status breaks as soon as the library acquires 5 physical copies of the same book.
- 2.
Invert high-level dependencies: Never let
LibraryServiceinstantiate SQL queries or a hardcoded fine formula. Depend onCatalogRepositoryandFineCalculatorabstractions so fakes can be injected in unit tests. - 3.
Decouple reservation alerts with Observer: When a book copy is returned, the library service should not hardcode SMS or email logic. Publish a domain event to
ReservationObserversubscribers.
How to think through this problem (5-step walkthrough)
In a 45-minute LLD interview, the key architectural themes are domain modeling separation (the conceptual book title vs physical inventory copies), Dependency Inversion Principle (DIP) (injecting persistence and fine policy abstractions into LibraryService), and Observer-based event dispatching (notifying patrons on reservation fulfillment). Scope the solution to catalog management, loan tracking, overdue fine computation, FIFO hold queues, and observer notifications. Mention hold expiration timers (48-hour pickup window) and member borrowing limits as extensions.
Not every noun in the prompt deserves its own class. Separate dumb data structs from stateful managers, and turn trivial nouns into fields or enums.
BookTitleRepresents the intellectual work (ISBN, title, author) and manages the FIFO reservation hold queue (std::deque<std::string> holdQueue_).
BookCopyRepresents a tangible physical item in stock with a unique barcode, rack location, CopyStatus (Available, Loaned, Reserved), and active loan metadata.
CatalogRepositoryDIP persistence contract declaring methods to add/find titles and copies, decoupling LibraryService from concrete storage mechanisms.
FineCalculatorDIP strategy contract declaring calculateFinePaise(daysOverdue), allowing daily flat fees, progressive tiering, or holiday exemptions.
ReservationObserverObserver contract receiving notifications when a reserved copy becomes available for a waiting patron.
LibraryServiceCore coordinator orchestrating borrowing, returns, holds, and fines through injected dependencies.
DueDate / BarcodeStringTrap noun β beginners often introduce dedicated DueDate, ReturnDate, or BarcodeString classes. A barcode is a primitive std::string, and due dates are cleanly modeled as integer day offsets or timestamps, avoiding gratuitous class bloat.
A beginner merges book metadata and physical loan status into a single Book class (isbn, title, barcode, isBorrowed). When the library owns three physical copies of "Clean Code", the system must duplicate author and title data three times, and managing a single unified hold queue across all three copies becomes a tangled mess. Furthermore, hardcoding SQL queries or a fixed fine formula inside LibraryService makes unit testing impossible without an external database.
Directly instantiating database clients inside LibraryService couples business logic to storage technology and prevents fast in-memory testing.
Hardcoding fine calculation logic inside the return workflow breaks OCP when policies change (e.g. grace periods, member discounts, tiered penalties).
Hardcoding SMS or email sending inside returnBook() tightly couples loan management to external messaging services.
- β
Work vs Item cardinality invariant: A single
BookTitle(identified by ISBN) can associate with zero or more physicalBookCopyinstances, but eachBookCopyreferences exactly one valid ISBN. - β
Reservation lock invariant: When a book copy is marked
CopyStatus::Reservedfor patron M, no other patron may borrow that copy until M's reservation is fulfilled or expires. - β
Dependency Inversion:
LibraryServicedepends exclusively on abstract interfaces (CatalogRepository,FineCalculator,ReservationObserver) injected via constructor, owning zero concrete database or notification instances.
Entities & design patterns used
Unlock Full UML Diagram & C++23 Solution
The complete UML diagram, production-ready C++23 code, follow-up extensions, and design pitfall analysis are part of Brute2Best Pro. All 7 foundation chapters are 100% free.
First anchor question per pattern, Part 1 LLD & Module 1 C++ basics are 100% Free forever.