Skip to content

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

  1. Register a member, in one of several categories.
  2. Add a title, and add copies of it.
  3. Borrow a copy of a title, if a copy is available and the member is allowed.
  4. Reserve a title when every copy is on loan, and be notified when one is returned.
  5. Return a copy at any branch.
  6. Renew a loan, if the title is not reserved by somebody else.
  7. Compute fines for an overdue loan, per member category.
  8. Refuse a loan and say why: no copy, fine limit reached, category limit reached.
  9. Withdraw a title, keeping the borrowing history.
  10. Produce reports: overdue loans, members with fines, titles with no available copies.
  11. 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::time called 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 if chain 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 -Werror with 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