Library management system, drawn five ways
Published . By the DiagramDesk team.
The library system is the first design exercise many people meet, because everyone knows what a library does. That familiarity is also the trap: the model most people draw first lends out a book, and a library never lends a book. It lends a copy.
EntitiesUse casesData flowClassesIssuing a copyMistakes
Start with the data: a book is not a copy
Most assignments give a paragraph like this: members borrow books, return them, may reserve a book that is out, and pay a fine if they return one late; librarians add books and register members. Read it for nouns and you get Member, Book, Loan, Reservation and Fine. Read it for what can be in two places at once and you find the one that matters: a library can own four copies of the same title, three of them on loan and one on the shelf.
So Book holds what is true of the title (the ISBN, the title, the year) and Copy holds what is true of one physical object: its own id and its shelf mark. The ISBN identifies an edition, not a volume, which is why it cannot be the key of the thing that gets lent.
The rest follows from asking each relationship its question in both directions, the habit the crow's foot guide recommends:
- A copy can go out on many loans over its life, one at a time; each loan is of exactly one copy.
- A member takes zero or more loans. Zero matters: a member who has just joined has none, and the model has to allow that.
- A reservation is for a book, not a copy. The member wants the next copy of that title that comes back, whichever it is.
- A loan leads to at most one fine, and most loans lead to none.
- Books and authors are many-to-many, so the join (Book author) is drawn as an entity, with a position so the names print in the order the title page gives them. Its key is the ISBN and the author together, so both of its lines are solid: identifying relationships.
Every other line in the model is dashed, a non-identifying relationship, because Copy, Loan, Reservation and Fine each have an id of their own. That holds even where the child cannot exist without its parent: every loan is of a copy, but it is identified by its own loan_id, not by the copy it is of.
Two attributes deserve a sentence each in a write-up. returned_on stays empty while the copy is out, so "which loans are open" is a query, not a flag that someone must remember to clear. And Fine is stored rather than worked out on demand, because the amount is fixed when it is charged: if the daily rate changes next year, last year's fines should not change with it.
Use cases: whose goal is it?
A use case is something an actor wants done, named as a verb phrase from that actor's side. At a staffed desk the member does not operate the system to borrow; the librarian issues the copy. That is why Issue a copy belongs to the librarian here. A library with self-service kiosks would give the member a Borrow use case instead, and the diagram should say which library you are describing.
Check borrowing rights is pulled out because two use cases always need it: issuing a new loan and renewing an old one both ask whether the member is under their limit and owes nothing. That is the job «include» is for. Charge a late fine is the opposite case: it happens only when a copy comes back late, so it extends Take back a copy rather than being part of it. The arrow of an «extend» points at the use case being extended, which is the detail most often drawn backwards. The use case page has the rule in one line.
The email service sits on the right as a secondary actor: the system uses it rather than the other way round. Sending reminders is started by the calendar, not by a person, and some courses want a Time actor for that; if yours does, draw it, and keep the email service as the channel.
The data flow diagram: follow a barcode
A level 1 DFD shows the main processes inside the system and every store they read or write. The quickest way to draw one is to follow a single piece of data. A barcode enters at the desk and becomes a loan; the loan sits in D2 until the copy comes back; a loan still open after its due date becomes a reminder. Each of those steps is a process, numbered so a level 2 diagram can expand it later. Registering a member is one more, process 5.0, and it is the only one that writes D1: leave it out and the store of members is read but never written, one of the mistakes in the list at the end of this page.
Two rules keep a DFD honest, and both are visible here. Data never flows straight from an outside entity into a store: the librarian cannot write to D2, only process 1.0 can. And every process has something in and something out; a process with only inputs is a black hole, one with only outputs is a miracle, and markers look for both. Notice also what is missing. There is no "Log in" process and no arrow for the librarian's password, because a DFD is about the data the library runs on, not the screens.
From entities to classes
The class diagram keeps the same five things but adds what each one can do. The methods are where the design decisions show: Member.canBorrow(today) is where the loan limit and the unpaid-fine rule live, so there is one place to change them; Loan.lateFee(today) works out what would be owed if the copy came back now, which the desk shows before anyone commits to a fine.
Book to Copy is drawn as composition, the filled diamond, because deleting a title from the catalogue removes its copies with it. Member to Loan is a plain association: when a member leaves, the library usually wants to keep the history of what was borrowed, so loans outlive the membership. Reservation.fulfil(copy) returns a Loan, which is the whole life of a reservation in one line: it waits until a copy comes back, then turns into a loan.
One sequence: issuing a copy
A sequence diagram answers "who asks whom, in what order" for one scenario. Issuing is the richest scenario in this system because two separate stores can each say no: the member may be at their limit or owe a fine, and the copy may be the one set aside for somebody else's reservation. The alt frame shows both outcomes without drawing the diagram twice.
The order of the messages is the point. Nothing is written to the loan records until both checks have come back, so a refused loan leaves no half-made record to clean up. The replies are dashed, as UML draws a return, and the desk is a participant in its own right rather than folded into "the system", which would hide who is asking.
The mistakes markers look for
- Lending the Book. A Loan joined to Book cannot say which of the four copies is on which member's shelf.
- An "available" column on Book. Whether a title is on the shelf is a count of its copies without an open loan. Store it, and it will disagree with the loans sooner or later.
- Reserving a copy. Nobody queues for copy 3 in particular; tie the reservation to the title.
- Member and Book as a bare many-to-many. The dates have nowhere to go. The join is the loan, and it needs to be an entity.
- An outside entity writing to a store in the DFD, or a store with arrows only in or only out.
- Log in as a use case that every other use case includes. Logging in is not anybody's goal; if the course requires it, show it once and do not wire it to everything.
If you are drawing this for coursework, treat the diagrams above as something to check your own against rather than to copy. Your brief will add or remove something (inter-library loans, e-books, a limit that depends on the kind of member), and the marks go to the decisions that follow from those details.
Keep going
- The online shopping system, where a basket turns into an order
- All the worked systems
- Draw your own ER diagram