Design a Library Management System
Members, books, copies, holds, and fines — the classic CRUD-heavy modelling exercise done cleanly.
Problem Statement
Design the object model for a Library Management System used by a public or university library. The system must catalog books, track physical book copies, register members, let members search the catalog, borrow and return copies, calculate fines for overdue returns, and maintain reservation queues when popular titles are unavailable.
The interview focus is the domain model and the seams around policy: searching, lending rules, fines, reservations, and notifications. A clean answer separates the bibliographic record from each physical copy, keeps loan state consistent, and avoids turning the service layer into a pile of conditional logic.
Business context
Library Management is a beginner-friendly but realistic LLD problem because it mixes CRUD-like catalog data with state transitions that must be correct: a copy cannot be loaned twice, a member cannot exceed the loan limit, and a returned copy may need to satisfy the oldest reservation before becoming generally available.
Interviewers use this problem to evaluate whether you can model Book versus BookCopy, use Repository-like collections for lookup, apply Strategy to catalog search, and apply Observer to reservation notifications without over-engineering the solution.
Functional Requirements
Store bibliographic books with ISBN, title, authors, and subject.
Track physical book copies by barcode and status: available, loaned, reserved, or lost.
Register members and enforce a maximum number of open loans per member.
Search the catalog by title, author, or subject.
Borrow an available copy of a requested ISBN and create a loan with a due date.
Return a borrowed copy, close the loan, and calculate an overdue fine.
Allow members to reserve a book when copies are unavailable or currently loaned.
Notify the next reserved member when a returned copy is held for them.
Non-Functional Requirements
State correctness
A copy must never be both available and loaned. All transitions go through BookCopy methods that validate the current status.
Extensibility
New search modes, fine policies, and notification channels should be additive. The lending workflow should not need a rewrite for each new rule.
Interactive latency
Catalog search and borrow should be fast enough for a librarian desk workflow. The reference solution uses in-memory scans; production would add indexes.
Fair reservations
Reservations for the same ISBN are served FIFO so the earliest waiting member gets the next returned copy.
Thread safety at hot spots
Copy status and member open-loan counts are synchronized so two desks cannot lend the same copy or exceed a member limit.
Requirement Clarification
QIs **Book** the same as a physical copy?
No. Book is the bibliographic record identified by ISBN. BookCopy is a physical item with a barcode and status. Multiple copies can point to the same book.
QHow long is a loan?
Assume a fixed 14-day loan period in the base design. A production design can extract this into a policy object.
QCan members reserve a specific barcode?
For the base design, reservations are at the ISBN level, not at the barcode level. The next returned copy of that ISBN can satisfy the oldest reservation.
QDo fines block future borrowing?
The reference solution calculates and returns the fine amount on return. Blocking behavior is a policy extension that can consult a member account balance.
QDo we need staff roles, payments, or a REST API?
No for the core LLD. Model the domain and service behavior first; staff auth, payment collection, and HTTP controllers are adapters around this model.
UML Class Diagram
Sequence Diagram
Entity Identification
Book
Bibliographic record for a title. It carries ISBN, title, authors, and subject, but has no availability state.
BookCopy
Physical copy identified by barcode. Owns the status transition methods so callers cannot casually flip between available, loaned, reserved, and lost.
CopyStatus
Enum describing a copy lifecycle: AVAILABLE, LOANED, RESERVED, and LOST.
Member
Registered library user. Tracks open loans and enforces the per-member loan limit through canBorrowMore and addLoan.
Catalog
In-memory repository for books and copies. It answers catalog search queries and finds an available copy for an ISBN.
SearchCriteria
Strategy interface for matching a book during catalog search. Concrete criteria handle title, author, and subject queries.
Loan
Record of one borrowing session: copy, member, issue date, due date, and optional return date.
Reservation
A waiting member's hold on a book. It records the book, member, creation time, and active flag, then becomes fulfilled when a copy is held.
FineService
Fine calculation policy. It multiplies overdue days by a configured daily fine and returns zero for on-time returns.
ReservationNotifier
Observer boundary for notifying a member that a reserved copy is ready. Email, SMS, app push, or test spies can implement it.
LibraryService
Application service and aggregate coordinator. It borrows, returns, reserves, tracks open loans by barcode, and owns reservation queues by ISBN.
Design Patterns Used
Catalog centralizes book and copy storage behind add, search, and availability lookup methods. The service asks the repository-like object for data instead of walking raw collections everywhere.
SearchCriteria lets title, author, and subject searches vary independently of Catalog.search. Adding ISBN or keyword search is a new criteria class, not an edit to the catalog loop.
ReservationNotifier decouples the reservation workflow from the notification channel. Returning a copy triggers notifyReady, while email, SMS, or app push remain outside the domain.
Step-by-Step Design
1Separate the title record from the copy state
Model Book as immutable catalog metadata and BookCopy as the mutable physical item. The barcode belongs to the copy; ISBN belongs to the book.
public final class BookCopy { private final String barcode; private final Book book; private CopyStatus status = CopyStatus.AVAILABLE; public synchronized void markLoaned() { requireStatus(CopyStatus.AVAILABLE); status = CopyStatus.LOANED; } }2Make catalog lookup repository-like
Catalog owns the collections and exposes meaningful operations: search and findAvailableCopy. This keeps data access out of LibraryService and makes a database-backed repository a clean future replacement.
3Use strategies for search criteria
The catalog does not switch on query type. It accepts a SearchCriteria and asks whether each book matches. Title, author, and subject searches are independent strategies.
interface SearchCriteria { boolean matches(Book book); } final class TitleCriteria implements SearchCriteria { public boolean matches(Book book) { return book.getTitle().toLowerCase(Locale.ROOT).contains(token); } }4Borrow by locking the copy and validating the member limit
LibraryService.borrow asks the catalog for an available copy, synchronizes on that copy, validates the status and member limit, marks the copy loaned, creates a Loan, indexes it by barcode, and adds it to the member.
synchronized (copy) { if (copy.getStatus() != CopyStatus.AVAILABLE) { throw new IllegalStateException("Copy was borrowed by another request"); } if (!member.canBorrowMore()) { throw new IllegalStateException("Member cannot borrow more books"); } copy.markLoaned(); }5Return closes the loan before changing copy availability
returnCopy removes the open loan, closes it with the return date, updates the member's open-loan set, calculates the fine, then decides what happens to the copy.
6Serve reservations through a FIFO queue and an observer
Reservations are grouped by ISBN. On return, the service polls the queue; if a reservation exists, the copy becomes RESERVED, the reservation is fulfilled, and ReservationNotifier is called.
if (next == null) { copy.markAvailable(); } else { next.fulfill(); copy.markReserved(); notifier.notifyReady(next.getMember(), copy); }
Complete Java Implementation
Explanation of Every Class
Book
Immutable bibliographic metadata. It validates ISBN, defensively copies the authors list, and exposes read-only getters so catalog records are not mutated accidentally.
BookCopy
Represents one physical item with a barcode and status. Synchronized transition methods enforce status rules for loaning, reserving, making available, and marking lost.
CopyStatus
Enum for the copy lifecycle: AVAILABLE, LOANED, RESERVED, and LOST. It keeps state values explicit and avoids magic strings.
Member
Stores member identity, maximum loan count, and an internal set of open loans. Synchronized methods protect the loan-limit invariant.
Catalog
In-memory repository for Book and BookCopy objects. It adds records, searches books with a supplied strategy, and finds the first available copy for an ISBN.
SearchCriteria
Strategy interface used by Catalog.search. Each implementation decides whether a book matches a particular query style.
TitleCriteria
Case-insensitive title search strategy. It lowercases the search token and checks whether the book title contains it.
AuthorCriteria
Case-insensitive author search strategy. It scans all authors of a book and succeeds when any author contains the token.
SubjectCriteria
Case-insensitive subject search strategy. It keeps subject filtering separate from title and author matching.
Loan
Borrowing session record. It knows the copy, member, issue date, due date, and return state; close prevents double returns.
Reservation
A member's waitlist entry for a book. It captures creation time for ordering and transitions from active to fulfilled exactly once.
ReservationNotifier
Observer interface called when a returned copy is reserved for the next waiting member. Implementations can send email, SMS, app push, or test notifications.
FineService
Overdue fine calculator. It validates the configured daily fine and charges only for days after the loan due date.
LibraryService
Coordinates the application flow. It borrows copies, returns copies, creates reservations, indexes open loans by barcode, and moves returned copies to either available or reserved.
Dry Run
Sample input
Catalog has Clean Code with ISBN ISBN-1 and one copy C1. Daily fine is 5. Member M1 can borrow 2 books. Member M2 reserves the title while C1 is loaned.
| Step | Action | Catalog and copy state | Loan state | Reservation state | Result |
|---|---|---|---|---|---|
| 1 | addBook and addCopy(C1) | Book indexed; C1 AVAILABLE | No open loans | No reservations | Catalog ready |
| 2 | search TitleCriteria clean | Book matches title search | No open loans | No reservations | Search returns Clean Code |
| 3 | borrow ISBN-1 by M1 on Jul 1 | C1 moves to LOANED | Loan L1 due Jul 15 | No reservations | Borrow succeeds |
| 4 | reserve book by M2 | C1 remains LOANED | L1 still open | Queue ISBN-1 contains R1 | Reservation recorded |
| 5 | return C1 on Jul 18 | C1 moves to RESERVED | L1 closes; fine is 15 | R1 fulfilled | M2 notified that C1 is ready |
The run shows the core invariants: search is read-only, borrow changes the copy to LOANED, a reservation waits by ISBN, and return computes three overdue days of fine before reserving the copy for the next member.
Complexity Analysis
| Operation | Time | Space | Note |
|---|---|---|---|
| Catalog.search | O(B × A) | O(R) | B books, A authors per book for author search, R matching results. |
| findAvailableCopy | O(C) | O(1) | Linear scan over copies in the in-memory reference catalog. |
| borrow | O(C) | O(1) | Dominated by finding an available copy; loan insertion and member update are constant time. |
| returnCopy | O(1) | O(1) | Open-loan lookup, fine calculation, and reservation queue poll are constant time. |
| reserve | O(1) | O(1) | Append to the per-ISBN queue. |
The reference solution favors clarity over indexing. A production repository would maintain maps by ISBN, title tokens, author tokens, and barcode so search and availability avoid full scans.
Extensibility
Database-backed repositories
Replace Catalog with BookRepository and CopyRepository implementations without changing the lending flow. Keep the service dependent on repository operations, not storage details.
More search strategies
Add IsbnCriteria, KeywordCriteria, or composed criteria. Catalog.search still receives a SearchCriteria and does not branch by type.
Flexible lending policy
Extract loan duration, renewal limits, and fine rules into policy objects when requirements differ for students, faculty, or premium members.
Notification channels
Implement ReservationNotifier with email, SMS, push notifications, or a fan-out composite. The return flow remains unchanged.
Alternative Designs
Full repository layer per aggregate
Create BookRepository, CopyRepository, LoanRepository, and ReservationRepository interfaces, then inject concrete in-memory or SQL implementations.
Tradeoffs
Closer to production and easier to persist, but more boilerplate for a beginner interview. Start with Catalog unless the interviewer asks about storage.
Policy objects for all rules
Extract LoanPolicy and FinePolicy so duration, borrowing eligibility, renewals, and fines vary by member type.
Tradeoffs
Very extensible, but can distract from the core model if introduced before the requirements demand it.
Event-driven reservation fulfillment
Publish a CopyReturned event and let a reservation handler reserve the copy and notify the member asynchronously.
Tradeoffs
Improves decoupling and reliability at scale, but introduces eventual consistency and more infrastructure than needed in the base design.
Common Mistakes
- ×
Treating Book and BookCopy as the same object, which makes multiple physical copies impossible to model cleanly.
- ×
Representing copy status as strings and updating it directly from the service instead of using transition methods.
- ×
Hard-coding title, author, and subject branches inside Catalog.search instead of using SearchCriteria strategies.
- ×
Forgetting to close the member's open loan on return, so the member permanently loses borrowing capacity.
- ×
Making returned copies immediately available even when there is an existing reservation queue.
- ×
Calling notification code directly through an email class instead of depending on ReservationNotifier.
- ×
Ignoring concurrency around the copy status check and mark operation.
Follow-up Interview Questions
QHow would you make catalog search faster?
Maintain indexes in the repository: ISBN to book, normalized title token to books, author token to books, and ISBN to available-copy queues. The domain model can stay the same.
QHow do you support renewals?
Add a renewal count and a LoanPolicy that checks whether the loan is open, not reserved by another member, and below the renewal limit before extending the due date.
QWhat happens if two librarians try to borrow the same copy?
The service synchronizes on the candidate BookCopy and rechecks the status before markLoaned. Only one request can complete the transition.
QHow would you collect fines?
Keep FineService responsible for calculation, then add a payment adapter or account ledger outside the core loan-closing flow. Calculation and collection are separate concerns.
QHow would you notify many channels at once?
Implement ReservationNotifier as a composite that invokes email, SMS, and app push observers. The return flow still depends on one interface.
Production Considerations
Persistence and transactions
Store books, copies, loans, members, and reservations in a database. Borrow and return should be transactional so copy status, loan rows, and reservation rows stay consistent.
Indexes
Add indexes on ISBN, barcode, normalized title, author, subject, and reservation queue position to avoid scanning as the library grows.
Concurrency control
Use row-level locks or optimistic version columns on BookCopy and Member to prevent double lending across multiple app instances.
Auditability
Record every loan, return, renewal, fine calculation, and status change with actor and timestamp. Libraries need dispute resolution and compliance history.
Operational notifications
Make notifications retryable and idempotent. A copy should not be released to the general pool just because an email provider is temporarily down.
What Interviewers Look For
Did you clearly separate Book from BookCopy?
Are copy status transitions guarded by the domain object rather than scattered assignments?
Is catalog lookup isolated behind repository-style methods?
Can new search criteria and notification channels be added without editing the core flow?
Do returns respect FIFO reservations before marking a copy available?
Did you discuss concurrency for the borrow path?
Quiz
0/5 answered
1.Why does the model need both **Book** and **BookCopy**?
2.Which part of the reference solution demonstrates Strategy?
3.Why is **ReservationNotifier** an interface?
4.What should happen when a loaned copy is returned and a reservation queue exists?
5.What is the main complexity bottleneck in the reference implementation?
Practice Variants
Add renewals
BeginnerAllow a member to renew an open loan when no other member has reserved the book. Add renewal limits and update due-date logic cleanly.
Add member tiers
IntermediateStudents, faculty, and guests have different loan limits, loan durations, and fine caps. Extract the policy without bloating LibraryService.
Add branch libraries
AdvancedSupport multiple branches, copy transfers, and reservations that can prefer a member's home branch before searching globally.
Flashcards
Cheat Sheet
Entities: Book, BookCopy, CopyStatus, Member, Catalog, SearchCriteria, Loan, Reservation, FineService, ReservationNotifier, LibraryService.
Patterns: Repository through Catalog, Strategy through SearchCriteria implementations, Observer through ReservationNotifier.
Borrow flow: find available copy by ISBN → lock copy → check member limit → mark loaned → create Loan → index by barcode → add to member.
Return flow: remove open loan → close loan → remove from member → calculate fine → poll reservation queue → reserve and notify or mark available.
Invariants: one status per copy; no loan without an available copy; member loan limit enforced; reservations served FIFO.
Complexity: search O(B×A), find available copy O(C), borrow O(C), return O(1), reserve O(1) in the in-memory reference design.
Extend: add repositories for persistence, policies for loan/fine rules, more SearchCriteria classes, and notifier implementations for real channels.
References
- BookPatterns of Enterprise Application Architecture — Repository — Martin Fowler
- BookHead First Design Patterns — Strategy and Observer — Freeman & Robson
- DocsRefactoring Guru — Observer Pattern