Library management
Books, copies, members and loans: separating a title from its physical copies, and enforcing loan limits and fines cleanly.
On the roadmap:Software Design · step 4: Low-level design: start with objects
Lesson 3 of 16 · 10 min read · quiz · exercise
The problem
A library has books, members and librarians. Members search the catalogue, borrow and return books, reserve a title that is out, and pay fines for late returns.
Entities and the title-versus-copy split
Figure SDA-LLD-03-1 · Library classes · © forcsguy.com
Book is the catalogue entry; BookCopy is a physical item with a status (available, loaned, reserved, lost). Searching works on Book; borrowing works on a BookCopy.
Borrow and return
Figure SDA-LLD-03-2 · Copy status over its life · © forcsguy.com
class LoanService {
constructor(private maxLoans = 5, private days = 14) {}
borrow(member: Member, copy: BookCopy): Loan {
if (member.activeLoans().length >= this.maxLoans) throw new Error("limit reached");
if (member.hasUnpaidFines()) throw new Error("pay fines first");
if (copy.status !== "AVAILABLE") throw new Error("not available");
copy.status = "LOANED";
return member.addLoan(new Loan(copy, addDays(now(), this.days)));
}
giveBack(loan: Loan, policy: FinePolicy): void {
loan.returnedAt = now();
const fine = policy.fine(loan, loan.returnedAt);
if (fine > 0) loan.member.addFine(fine);
loan.copy.status = nextWaiting(loan.copy) ? "RESERVED" : "AVAILABLE";
}
}
Design notes
- Rules in one service. Limits, fines and availability checks live in
LoanService, so no path can bypass them. - Fines as a strategy. Rates, grace periods and caps change; the interface keeps that separate.
- Reservations are a queue per title. On return, the service notifies the first member (Observer), who has a limited time to collect.
- Search across title, author and subject needs an index; mention a search engine if the catalogue is large.
- Concurrency: two members borrowing the same copy at once must not both succeed; check and set the status atomically.
- Extensions: renewals (limited, blocked if reserved), different loan periods by member type, digital lending.
Real-world reading
Related reading
- Microservices Patterns CatalogChris Richardson · microservices.ioDocumentation
- Pattern: SagaChris Richardson · microservices.ioDocumentation
- Awesome MicroservicesMehdi Fornos · mfornosGitHub
- Microservices PatternsChris Richardson · ManningBooks
Show 6 moreShow fewer
- Uber Engineering — Where the Digital World Meets the Physical OneUber engineers · UberBlogs
- Azure Architecture CenterMicrosoft · Microsoft AzureDocumentation
- Design Patterns CatalogueRefactoring GuruDocumentation
- GRIT: Protocol for Distributed Transactions across Microservices at eBayeBay engineers · eBayCase Studies
- Engineering BlogsKilim Choi · kilimchoiGitHub
- Docker in Production at TreehouseTreehouse engineers · TreehouseCase Studies
Check your understanding
Question 1 of 3
0 correct so far
Why separate Book from BookCopy?
Practise it: URL shortener
Everything below is already set up for this lesson: change the design, run the traffic, and see whether you meet the goal.
- 1The task
- 2Build and test
Read-heavy, a few links are very popular.
Add or remove parts, move traffic up and down, and break something to see what gives way first.
Try it yourself
Add fines for late returns and a reservation queue per title. Describe the classes and the return flow.
Click what a strong design here would need:
More in Design practice
© 2026 forcsguy.com. Original lesson text and diagrams. Books and sites linked above belong to their authors.