Capstone 1 — Library Management System¶
Scope: a term's work · Prerequisites: Modules 1–15 · Builds on: nothing — do not reuse the lab system's code
Note before you start. The sixteen labs built a campus lending system. If you completed them, that system is your worked example, not your starting point: this project is a larger system with acquisitions, reservations, fines and multiple branches, and you are expected to design it yourself. The design report's first line should say what you learned from the lab system least, not most.
1. Problem statement¶
A public library with three branches needs to manage its collection, its members, and the movement of books between them.
The library acquires books from suppliers and holds multiple copies of a title, not one. Members can borrow, reserve a title that is fully on loan, renew a loan, and return a book to a branch other than the one they borrowed it from. Overdue loans accrue fines that vary by member category, and a member whose fines are unpaid beyond a limit cannot borrow. Titles are sometimes withdrawn from the collection, which must not lose the history of who borrowed them.
The system must survive being closed and reopened, and it must behave sensibly when a member of staff edits its data file by hand — because they will.
2. Actors¶
| Actor | What they do | What the system owes them |
|---|---|---|
| Member | Searches, borrows, reserves, renews, returns, asks what they owe | Correct availability, correct fines, a clear refusal when an operation is not allowed |
| Librarian | Issues and returns books, registers members, handles reservations | Speed at the desk, and a way to see the state of everything |
| Acquisitions officer | Adds titles and copies, withdraws them | Stock levels that match reality, and a history that survives withdrawal |
| Administrator | Sets loan periods and fine rates per category | Configuration without recompiling the rules |
3. Use cases¶
- Register a member, in one of several categories.
- Add a title, and add copies of it.
- Borrow a copy of a title, if a copy is available and the member is allowed.
- Reserve a title when every copy is on loan, and be notified when one is returned.
- Return a copy at any branch.
- Renew a loan, if the title is not reserved by somebody else.
- Compute fines for an overdue loan, per member category.
- Refuse a loan and say why: no copy, fine limit reached, category limit reached.
- Withdraw a title, keeping the borrowing history.
- Produce reports: overdue loans, members with fines, titles with no available copies.
- Save and load everything; reject a corrupted file with a message that names the line.
4. Suggested classes¶
| Class | Responsibility, in one sentence | Notes |
|---|---|---|
Title |
The bibliographic record: identifier, author, subject | No copies, no availability — that is Copy's business |
Copy |
One physical book, of one title, held at one branch | Has its own identifier; a title has many |
Member |
A person who may borrow, with a category and a borrowing history | Enforces its own limits and fine total |
MemberCategory |
A category's limits and rates | Values, or a LendingPolicy input |
LendingPolicy |
How long a member of this category may keep a copy, and at what rate fines accrue | An interface: this is where the rules vary |
Loan |
One copy out to one member, with a due date and a return date | Aggregates a copy and a member; owns neither |
Reservation |
A member's claim on a title when no copy is available | Ordered; the next member to be served |
Branch |
A location holding copies | Owns no copies; references them |
Catalogue |
The titles and copies, searchable | Composition over copies |
Notifications |
Tells reservations when a copy is returned | The observer's subject |
FineCalculator |
Turns overdue days, category and title kind into an amount | Deterministic and testable: a pure function behind an interface |
Library |
Coordinates the operations, owns the collections | The one place an operation is a transaction |
The class worth the most marks is FineCalculator. Its inputs are values, its output is a number, and
every rule about money lives there — which is the difference between a system whose fine rules can be
tested and one where they are spread across the desk operations.
5. Relationships¶
Library ◆── Catalogue composition: the catalogue dies with the library
Library ◆── vector<Member> composition: ditto
Catalogue ◆── vector<Title> composition
Title ◇── vector<Copy> aggregation: a copy can move between branches without the title dying
Loan ────> Copy association: a loan refers to a copy it does not own
Loan ────> Member association
Reservation ────> Title association
Library ┈┈> LendingPolicy dependency: injected, chosen by member category
Library ┈┈> FineCalculator dependency: injected
Notifier <|── EmailNotifier inheritance for substitution, not reuse
Draw this yourself, from your own code, and check it line by line. Any arrow you cannot justify in one sentence is a design mistake rather than a diagram mistake.
6. Design constraints¶
- Availability is never stored twice. A copy's status is derived from the loans that refer to it, or owned by exactly one object with every operation going through it. Two independent "is it out?" answers is the classic invariant bug in this domain — and you will be asked to demonstrate that it cannot happen in your design.
- A copy is not a title. Multiple copies of a title, each with its own identifier and history, is the requirement that makes the domain interesting; collapsing them loses the ability to answer "how many copies do we own".
- Money is integer pence, never
double. Say why in the report. - Time is injected, not read from the clock inside the domain.
std::timecalled in the middle of a rule makes the rule untestable; pass "today" in. - The fine rules vary by configuration — a strategy or a policy object, chosen where the context is
known, never an
ifchain over categories. - Reservations notify, which is an observer with the lifetime question answered in the design: who unregisters a reservation, and when.
- Format: one documented text format with a version marker and an escape rule; loading a file written by a later version must be refused with a message, not misread.
7. Milestones¶
| # | Milestone | Done when |
|---|---|---|
| 1 | Design | A UML class diagram with multiplicities; every class's responsibility in one sentence; the invariant of the copy/loan relationship stated |
| 2 | Skeleton | Titles, copies and members exist, with invariants enforced in constructors and no way to break them from outside |
| 3 | Lending | Borrow, return and renew work, with refusals that name the reason |
| 4 | Policy | Loan periods and fines come from an injected policy; two implementations exist and are swapped by configuration |
| 5 | Reservations and notifications | A returned copy notifies the next reservation, and the lifetime question is answered in code and in the report |
| 6 | Persistence | Save, load, a documented format, a round trip preserving every field including an empty catalogue, and three hand-edited corruptions rejected with line numbers |
| 7 | Tests and report | The suite covers invariants, boundaries and failures; a deliberate bug was caught; the report names the decision you would reverse and its cost |
8. Minimum requirements¶
- [ ] Titles, copies, members and loans, with no way to construct an invalid one from outside
- [ ] Borrow, return, renew and reserve, each refusing invalid requests with a reason
- [ ] Loan periods and fine rates that vary by member category, injected rather than hard-coded
- [ ] Fines computed in integer pence, with a cap and a category-based rate
- [ ] Persistence with a version marker and an escape rule, and a round trip that preserves every field
- [ ] Three hand-edited corruptions rejected with line numbers, leaving the loaded state untouched
- [ ] At least two patterns, each justified by a named requirement
- [ ] One pattern considered and declined, with the reason
- [ ] A test suite with assertions covering invariants, boundaries and failure paths
- [ ] It builds with
-Wall -Wextra -Werrorwith no warnings
9. Advanced requirements¶
- [ ] A reservation queue with correct ordering and evidence: reservations served first come, first served, demonstrated by a scripted sequence
- [ ] Non-member and staff categories added without editing the lending operations — the change-cost count in the report
- [ ] Multiple branches, with a copy transferable between them, and the report's file count for the change that made transfers possible
- [ ] Withdrawal preserving history: a withdrawn title no longer lends, but past loans still report
- [ ] A command line or scripted batch mode that drives the domain without duplicating it
- [ ] A second output format (for example CSV for a report) behind the same interface as the first
- [ ] A fine limit that blocks borrowing, with the refusal naming the amount and the limit
10. Testing requirements¶
Cover, with assertions and a summary count rather than printouts:
- Invariants: a copy cannot be on loan to two members; a title's copy count matches the copies; a member's fine total equals the sum of their unpaid fines
- Boundaries: the last available copy; a loan due exactly today; one day past the cap; a fine one penny under and exactly at the limit; a member at their category's item limit
- Failure paths: borrowing with no copy available; returning a copy not on loan; renewing a reserved title; loading a truncated file; a negative day count
- Round trip: populated and empty catalogues, compared field by field, including a title containing the separator character
- One deliberate bug, introduced and caught — the assertion that failed must be in your notes
11. Extension ideas¶
- Membership expiry, with borrowing refused after a date.
- A hold on a title that is on order from the supplier, distinct from a reservation.
- Inter-branch transfer requests, with a queue and a state per request.
- A borrowing history view per member, exported to a file.
- Self-service renewal with a limit on the number of renewals, and a refusal that says why.
- A recommendation rule: "members who borrowed this also borrowed" — and a measurement of whether the design made it easy or hard, which belongs in the report.
12. Evaluation checklist¶
Run this before submitting anything. Every box needs evidence you can point at.
- [ ] The diagram matches the declarations, including multiplicities
- [ ] No invariant can be broken from outside the class that owns it — demonstrated by trying
- [ ] Money is integer pence, and the report explains why
- [ ] Time is injected, and a rule can be tested without waiting for a date to arrive
- [ ] Lending policy is injected, and two implementations exist
- [ ] Adding a member category touched at most two files — the count is in the report
- [ ] A returned copy notifies the next reservation, and nothing is notified after destruction
- [ ] The round trip preserves every field, including an empty catalogue — output pasted
- [ ] Three corruptions were rejected with line numbers, and the loaded state was left untouched
- [ ] The suite fails when a deliberate bug is introduced — recorded, with the test kept
- [ ] One pattern was considered and declined, in writing
- [ ] The report names the decision I would reverse and the cost of reversing it
Related: Capstone options · Projects and the rubric · Module 16 — Capstone · Module 15 — Patterns