Library Management System
Problem Statement
Section titled “Problem Statement”Design a library management system that handles book inventory, member management, book borrowing and returning, reservations, and fine calculations. The system should track book copies, manage due dates, and handle multiple branches.
Requirements
Section titled “Requirements”Functional Requirements
Section titled “Functional Requirements”- Add, update, and remove books from the catalog
- Register and manage library members
- Issue books to members
- Return books and calculate fines
- Reserve books that are currently borrowed
- Search books by title, author, ISBN, or category
- Track book copies across multiple branches
- Generate reports on popular books and overdue items
- Support different member types with different borrowing limits
- Send notifications for due dates and reservations
Non-Functional Requirements
Section titled “Non-Functional Requirements”- Handle concurrent book checkouts
- Accurate fine calculations
- Scalable for large book collections
- Fast search operations
- Data consistency for inventory
Simplified Class Diagram
Section titled “Simplified Class Diagram”Simplified Overview
Section titled “Simplified Overview”Detailed Class Diagram
Section titled “Detailed Class Diagram”Key Design Patterns
Section titled “Key Design Patterns”- Singleton Pattern: LibrarySystem as central management point
- Factory Pattern: Create different member types
- Strategy Pattern: Different fine calculation strategies
- Observer Pattern: Notifications for due dates
- Repository Pattern: Catalog for book management
Design Pattern Diagrams
Section titled “Design Pattern Diagrams”1. Strategy Pattern - Membership Policies (Composition over Inheritance)
Section titled “1. Strategy Pattern - Membership Policies (Composition over Inheritance)”2. Observer Pattern - Due Date Notifications
Section titled “2. Observer Pattern - Due Date Notifications”3. Repository Pattern - Catalog Management
Section titled “3. Repository Pattern - Catalog Management”Code Snippets
Section titled “Code Snippets”Issue Book
Section titled “Issue Book”public class LibrarySystem { public Loan issueBook(BookItem bookItem, Member member) throws LibraryException { synchronized(this) { // Validate member can borrow if (!member.canBorrowMore()) { throw new LibraryException("Member has reached borrowing limit"); }
// Check for outstanding fines if (hasOutstandingFines(member)) { throw new LibraryException("Member has outstanding fines"); }
// Check book availability if (!bookItem.isAvailable()) { throw new LibraryException("Book is not available"); }
// Create loan Loan loan = new Loan(bookItem, member);
// Calculate due date based on member type int loanPeriod = getLoanPeriod(member.getMemberType()); Calendar cal = Calendar.getInstance(); cal.add(Calendar.DAY_OF_MONTH, loanPeriod); loan.setDueDate(cal.getTime());
// Update book status bookItem.updateStatus(BookStatus.BORROWED);
// Save loan loans.put(loan.getLoanId(), loan);
// Check and fulfill reservations fulfillPendingReservations(bookItem.getBook());
return loan; } }
private int getLoanPeriod(MemberType type) { switch(type) { case STUDENT: return 14; case FACULTY: return 30; case PREMIUM: return 21; default: return 14; } }}Return Book and Calculate Fine
Section titled “Return Book and Calculate Fine”public class LibrarySystem { public Fine returnBook(String barcode) throws LibraryException { synchronized(this) { // Find loan Loan loan = findLoanByBarcode(barcode); if (loan == null) { throw new LibraryException("No active loan found for barcode: " + barcode); }
// Set return date loan.setReturnDate(new Date());
// Calculate fine if overdue Fine fine = null; if (loan.isOverdue()) { double fineAmount = fineCalculator.calculateFine(loan); fine = new Fine(loan, fineAmount); loan.setFine(fineAmount); }
// Update book status loan.getBookItem().updateStatus(BookStatus.AVAILABLE);
// Check for reservations fulfillReservation(loan.getBookItem());
return fine; } }
private void fulfillReservation(BookItem bookItem) { for (Reservation reservation : reservations) { if (reservation.getBook().equals(bookItem.getBook()) && reservation.getStatus() == ReservationStatus.PENDING) { // Notify member notificationService.sendReservationNotification(reservation); reservation.setStatus(ReservationStatus.FULFILLED); bookItem.updateStatus(BookStatus.RESERVED); break; } } }}Fine Calculator
Section titled “Fine Calculator”public class StandardFineCalculator implements FineCalculator { private static final double DAILY_FINE_RATE = 1.0; private static final double MAX_FINE = 50.0;
@Override public double calculateFine(Loan loan) { if (!loan.isOverdue()) { return 0.0; }
Date returnDate = loan.getReturnDate() != null ? loan.getReturnDate() : new Date();
long overdueDays = calculateOverdueDays(loan.getDueDate(), returnDate); double fine = overdueDays * DAILY_FINE_RATE;
// Cap at maximum fine return Math.min(fine, MAX_FINE); }
private long calculateOverdueDays(Date dueDate, Date returnDate) { long diffMillis = returnDate.getTime() - dueDate.getTime(); return Math.max(0, diffMillis / (1000 * 60 * 60 * 24)); }}Search Books
Section titled “Search Books”public class Catalog { public List<Book> searchByTitle(String title) { return books.values().stream() .filter(book -> book.getTitle().toLowerCase() .contains(title.toLowerCase())) .collect(Collectors.toList()); }
public List<Book> searchByAuthor(String author) { return books.values().stream() .filter(book -> book.getAuthors().stream() .anyMatch(a -> a.toLowerCase().contains(author.toLowerCase()))) .collect(Collectors.toList()); }
public Book searchByISBN(String ISBN) { return books.get(ISBN); }}Reserve Book
Section titled “Reserve Book”public class LibrarySystem { public Reservation reserveBook(Book book, Member member) throws LibraryException { // Check if book has available copies long availableCopies = catalog.getBookItems().stream() .filter(item -> item.getBook().equals(book)) .filter(BookItem::isAvailable) .count();
if (availableCopies > 0) { throw new LibraryException("Book is available, reservation not needed"); }
// Check if member already has reservation boolean hasReservation = reservations.stream() .anyMatch(r -> r.getMember().equals(member) && r.getBook().equals(book) && r.getStatus() == ReservationStatus.PENDING);
if (hasReservation) { throw new LibraryException("Member already has a reservation for this book"); }
Reservation reservation = new Reservation(book, member); reservations.add(reservation);
return reservation; }}Extension Points
Section titled “Extension Points”- Add digital book lending (e-books)
- Implement inter-branch book transfers
- Add book recommendation system
- Support different loan periods for different book types
- Implement waiting list when multiple reservations exist
- Add barcode/RFID scanning integration
- Support bulk operations for librarians
- Add analytics and reporting dashboard
- Implement late fee payment integration
- Support book renewal with limits