📂
Interview Prep
LLD Questions
LLD Questions
  • LLD Introduction
  • Meeting Scheduler
  • Distributed Cache System
  • Rate limiter
  • Multi-Tier Elevator System
  • MyGate System
  • Uber Sytem LLD
  • Parking Lot System
  • Online book store
  • Library Management System
  • Movie Ticket Booking System
  • Hotel Management System
  • File Storage System
    • Solution 2
  • Chat Application
  • Social Media Platform
  • Notification System
  • Airline Reservation System
  • ATM System
  • E-commerce Website
  • Food Delivery System
  • Shopping Cart System
  • URL Shortener system
  • Chess Tournament System
  • Threading therory
  • OOP questions
Powered by GitBook
On this page

Library Management System

Low-Level Design (LLD) for a Library Management System in Java

The Library Management System is a software application designed to manage the day-to-day operations of a library, including tracking books, managing members, and overseeing the lending and returning of books. The system should also handle overdue books, fines, and send reminders for due or overdue returns.

In this LLD, we will cover the following core functionalities:

  • Entities and Relationships: What are the main entities (books, members, loans, etc.) and how do they relate to each other?

  • Book Lending and Returning: How will we handle lending and returning of books, and track the process efficiently?

  • Overdue Management: How will we handle overdue books, manage fines, and send reminders?

  • Design Patterns Used: We'll incorporate several design patterns such as Factory Pattern, Observer Pattern, Strategy Pattern, and Singleton Pattern to create a modular, scalable design.


Key Entities and Relationships

Entities:

  • Book: Represents a book in the library, with properties like title, author, ISBN, availability status, etc.

  • Member: Represents a library member, with properties like name, membership ID, and a list of books currently borrowed.

  • Loan: Represents a loan transaction, keeping track of the book, the member, the due date, and the status (lent, returned, overdue).

  • Fine: Represents fines associated with overdue books.

Relationships:

  • A Member can borrow multiple Books through Loans.

  • A Book can be associated with multiple Loans over time.

  • Loans track the lending date, due date, and whether the book is overdue or returned.

  • Fines are associated with Loans if a book is returned past the due date.

Design Patterns Used

  • Factory Pattern: To create different entities like Book, Member, and Loan.

  • Observer Pattern: To send notifications (like reminders for overdue books).

  • Strategy Pattern: For calculating fines based on different rules.

  • Singleton Pattern: To manage the library system and ensure only one instance of the library exists.


Classes and Data Structures

1. Book Class

The Book class represents a book in the library system.

class Book {
    private String title;
    private String author;
    private String ISBN;
    private boolean isAvailable;

    public Book(String title, String author, String ISBN) {
        this.title = title;
        this.author = author;
        this.ISBN = ISBN;
        this.isAvailable = true; // Book is available by default
    }

    public boolean isAvailable() {
        return isAvailable;
    }

    public void setAvailability(boolean availability) {
        this.isAvailable = availability;
    }

    public String getTitle() {
        return title;
    }

    public String getISBN() {
        return ISBN;
    }
}

2. Member Class

The Member class represents a library member and their current loans.

import java.util.List;

class Member {
    private String name;
    private String memberId;
    private List<Loan> loans;

    public Member(String name, String memberId) {
        this.name = name;
        this.memberId = memberId;
    }

    public void borrowBook(Book book, Library library) {
        if (book.isAvailable()) {
            Loan loan = library.issueBook(this, book);
            loans.add(loan);
        } else {
            System.out.println("Book is not available for borrowing.");
        }
    }

    public void returnBook(Book book, Library library) {
        Loan loan = findLoanForBook(book);
        if (loan != null) {
            loan.setReturned(true);
            library.receiveBook(this, loan);
        } else {
            System.out.println("This book is not on loan to this member.");
        }
    }

    private Loan findLoanForBook(Book book) {
        for (Loan loan : loans) {
            if (loan.getBook().equals(book) && !loan.isReturned()) {
                return loan;
            }
        }
        return null;
    }

    public String getName() {
        return name;
    }

    public String getMemberId() {
        return memberId;
    }
}

3. Loan Class

The Loan class represents a transaction where a book is borrowed by a member.

import java.util.Date;

class Loan {
    private Book book;
    private Member member;
    private Date issueDate;
    private Date dueDate;
    private boolean isReturned;

    public Loan(Book book, Member member, Date issueDate, Date dueDate) {
        this.book = book;
        this.member = member;
        this.issueDate = issueDate;
        this.dueDate = dueDate;
        this.isReturned = false;
    }

    public boolean isOverdue() {
        return !isReturned && new Date().after(dueDate);
    }

    public Book getBook() {
        return book;
    }

    public Date getDueDate() {
        return dueDate;
    }

    public boolean isReturned() {
        return isReturned;
    }

    public void setReturned(boolean isReturned) {
        this.isReturned = isReturned;
    }
}

4. Fine Class

The Fine class represents fines for overdue books.

class Fine {
    private Loan loan;
    private double amount;

    public Fine(Loan loan, double amount) {
        this.loan = loan;
        this.amount = amount;
    }

    public Loan getLoan() {
        return loan;
    }

    public double getAmount() {
        return amount;
    }
}

5. Library Class (Singleton Pattern)

The Library class is the central class that manages the system and ensures only one instance of the library exists.

import java.util.*;

class Library {
    private static Library instance;
    private Map<String, Book> books;
    private List<Loan> activeLoans;

    private Library() {
        books = new HashMap<>();
        activeLoans = new ArrayList<>();
    }

    public static Library getInstance() {
        if (instance == null) {
            instance = new Library();
        }
        return instance;
    }

    public void addBook(Book book) {
        books.put(book.getISBN(), book);
    }

    public Loan issueBook(Member member, Book book) {
        Date issueDate = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(issueDate);
        calendar.add(Calendar.DAY_OF_YEAR, 14); // Default 14-day loan
        Date dueDate = calendar.getTime();

        Loan loan = new Loan(book, member, issueDate, dueDate);
        activeLoans.add(loan);
        book.setAvailability(false); // Book is now unavailable
        return loan;
    }

    public void receiveBook(Member member, Loan loan) {
        loan.setReturned(true);
        loan.getBook().setAvailability(true); // Mark book as available
    }

    public List<Fine> checkOverdueBooks() {
        List<Fine> fines = new ArrayList<>();
        for (Loan loan : activeLoans) {
            if (loan.isOverdue()) {
                double fineAmount = calculateFine(loan);
                fines.add(new Fine(loan, fineAmount));
            }
        }
        return fines;
    }

    private double calculateFine(Loan loan) {
        long daysOverdue = (new Date().getTime() - loan.getDueDate().getTime()) / (1000 * 60 * 60 * 24);
        return daysOverdue * 1.0; // Fine of $1 per day
    }
}

6. FineCalculator Strategy (Strategy Pattern)

The FineCalculator class implements the Strategy Pattern to calculate fines differently based on rules or conditions.

interface FineCalculator {
    double calculateFine(Loan loan);
}

class StandardFineCalculator implements FineCalculator {
    @Override
    public double calculateFine(Loan loan) {
        long daysOverdue = (new Date().getTime() - loan.getDueDate().getTime()) / (1000 * 60 * 60 * 24);
        return daysOverdue * 1.0; // $1 per day
    }
}

class PremiumFineCalculator implements FineCalculator {
    @Override
    public double calculateFine(Loan loan) {
        return 0; // No fine for premium members
    }
}

7. Notification System (Observer Pattern)

The NotificationSystem uses the Observer Pattern to notify members about overdue books and fines.

interface Observer {
    void update(String message);
}

class MemberObserver implements Observer {
    private Member member;

    public MemberObserver(Member member) {
        this.member = member;
    }

    @Override
    public void update(String message) {
        System.out.println("Notification to " + member.getName() + ": " + message);
    }
}

class NotificationSystem {
    private List<Observer> observers = new ArrayList<>();

    public void addObserver(Observer observer) {
        observers.add(observer);
    }

    public void notifyObservers(String message) {
        for (Observer observer : observers) {
            observer.update(message);
        }
    }
}

Main Class to Demonstrate the System

public class LibraryApplication {
    public static void main(String[] args) {
        // Initialize the library
        Library library = Library.getInstance();

        // Create some books
        Book book1 = new Book("The Great Gatsby", "F. Scott Fitzgerald", "9780743273565");
        Book book2 = new Book("1984", "George Orwell", "9780451524935");
        
        library.addBook(book1);
        library.addBook(book2);

        // Create a member
        Member member = new Member("John Doe", "M001");

        // Borrow books
        member.borrowBook(book1, library);
        
        // Create a notification system
        NotificationSystem notificationSystem = new NotificationSystem();
        notificationSystem.addObserver(new MemberObserver(member));
        
        // Check for overdue books (just after borrowing)
        List<Fine> fines = library.checkOverdueBooks();
        for (Fine fine : fines) {
            notificationSystem.notifyObservers("Fine for overdue book: " + fine.getAmount());
        }
    }
}

Design Patterns Used

  1. Factory Pattern: The LibraryFactory or UserFactory class (not explicitly shown in code) could be used to create different entities like Book, Member, Loan, and Fine objects dynamically.

  2. Strategy Pattern: The FineCalculator interface and its implementations (StandardFineCalculator, PremiumFineCalculator) allow the calculation of fines to be easily modified or extended.

  3. Observer Pattern: The NotificationSystem and Observer pattern are used to notify members about overdue books and fines.

  4. Singleton Pattern: The Library class is implemented as a singleton to ensure only one instance of the library exists.


Conclusion

The Library Management System uses design patterns like Factory, Strategy, Observer, and Singleton to ensure modularity, flexibility, and maintainability. It manages entities such as Books, Members, Loans, and Fines, while efficiently tracking book lending, returns, overdue management, and sending notifications to members.

PreviousOnline book storeNextMovie Ticket Booking System

Last updated 2 months ago