Skip to content

About

Low-Level Design implementation of a Library Management System in Java, demonstrating OOP and SOLID principles through a layered architecture (Model/Repository/Service). Supports book cataloging, member registration, and issue/return workflows with proper validation and exception handling.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

Library Management System — Low-Level Design (LLD)

1. Project Overview

A plain-Java, in-memory implementation of a Library Management System, built as a Low-Level Design exercise. It models real library operations — cataloging books, registering members, issuing and returning books — using clear separation of responsibilities, interface-driven design, and SOLID principles. No external frameworks are required to build or run it.

2. Problem Statement

Design and implement a Library Management System that supports:

  • Adding and managing books in the library
  • Registering and managing members
  • Issuing a book to a member
  • Returning a book
  • Tracking whether a book is available or issued
  • Preventing issuing of unavailable (already-issued) books

3. High-Level Design

The system is split into four layers, each with one clear job:

┌─────────────────────────────────────────────────────────┐
│  Main (demo / entry point)                               │
├─────────────────────────────────────────────────────────┤
│  Service Layer      -> LibraryService / LibraryServiceImpl│
│  (business rules: issue/return validation)                │
├─────────────────────────────────────────────────────────┤
│  Repository Layer    -> BookRepository / MemberRepository  │
│  (storage abstraction — currently in-memory)               │
├─────────────────────────────────────────────────────────┤
│  Model Layer         -> Book, Member, IssueRecord, Status  │
│  (plain data + minimal self-contained behavior)             │
└─────────────────────────────────────────────────────────┘

Why this shape?

  • Models stay dumb. Book and Member only know about their own state (e.g. a Book can mark itself issued/available). They don't know how they're stored or what business rules govern issuing — that logic doesn't belong to them.
  • Repositories own storage. BookRepository / MemberRepository are interfaces; InMemoryBookRepository / InMemoryMemberRepository are the current implementations. Swapping in a database-backed repository later requires zero changes to the service or model layers.
  • The service owns the rules. All business logic — "you can't issue an already-issued book," "you can't return a book that isn't checked out" — lives in LibraryServiceImpl, which depends only on the repository interfaces (constructor injection), never the concrete in-memory classes.

SOLID principles applied

Principle Where it shows up
Single Responsibility Book/Member hold state only; LibraryServiceImpl holds business rules; repositories handle storage only.
Open/Closed New storage backends can be added by implementing BookRepository/MemberRepository without modifying LibraryServiceImpl.
Liskov Substitution Any BookRepository/MemberRepository implementation can replace InMemoryBookRepository/InMemoryMemberRepository without breaking the service.
Interface Segregation Book storage and member storage are separate interfaces — a consumer needing only member data isn't forced to depend on book methods.
Dependency Inversion LibraryServiceImpl depends on BookRepository/MemberRepository abstractions, injected via its constructor, not concrete classes.

4. Key Classes and Responsibilities

Model (com.library.model)

  • Book — id, ISBN, title, author, and current BookStatus; can mark itself issued/available.
  • BookStatus — enum: AVAILABLE, ISSUED.
  • Member — id, name, email, and the set of book ids currently checked out to them.
  • IssueRecord — one lending transaction (book, member, issue date, return date); preserves full lending history, not just current state.

Repository (com.library.repository)

  • BookRepository / InMemoryBookRepository — CRUD-style storage for books.
  • MemberRepository / InMemoryMemberRepository — CRUD-style storage for members.

Service (com.library.service)

  • LibraryService — public contract: add book, register member, issue, return, list/search books.
  • LibraryServiceImpl — enforces the rules: a book must exist and be available to be issued; a book must be currently issued to that specific member to be returned.

Exception (com.library.exception)

  • LibraryException — common base for all business exceptions.
  • BookNotFoundException, MemberNotFoundException — referenced entity doesn't exist.
  • BookNotAvailableException — attempted to issue a book that's already checked out.
  • BookNotIssuedException — attempted to return a book that isn't checked out (or not to that member).
  • DuplicateBookException, DuplicateMemberException — attempted to register a duplicate id.

Entry point

  • Main — wires the in-memory repositories and service together and runs a walkthrough demo (add books, register members, issue, a blocked double-issue, return, re-issue).
  • LibraryServiceTest (in src/test) — a small, dependency-free sanity-test runner covering the core rules.

5. Project Structure

library-management-system/
├── README.md
├── run.sh
└── src/
    ├── main/java/com/library/
    │   ├── Main.java
    │   ├── model/
    │   │   ├── Book.java
    │   │   ├── BookStatus.java
    │   │   ├── Member.java
    │   │   └── IssueRecord.java
    │   ├── repository/
    │   │   ├── BookRepository.java
    │   │   ├── InMemoryBookRepository.java
    │   │   ├── MemberRepository.java
    │   │   └── InMemoryMemberRepository.java
    │   ├── service/
    │   │   ├── LibraryService.java
    │   │   └── LibraryServiceImpl.java
    │   └── exception/
    │       ├── LibraryException.java
    │       ├── BookNotFoundException.java
    │       ├── MemberNotFoundException.java
    │       ├── BookNotAvailableException.java
    │       ├── BookNotIssuedException.java
    │       ├── DuplicateBookException.java
    │       └── DuplicateMemberException.java
    └── test/java/com/library/
        └── LibraryServiceTest.java

6. Instructions to Run

Requires JDK 11+ (no external dependencies, build tools, or libraries needed).

Option A — using the provided script:

./run.sh          # builds everything and runs the demo (Main)
./run.sh test     # builds everything and runs the sanity test suite

Option B — manually with javac/java:

mkdir -p out
find src/main/java src/test/java -name "*.java" > sources.txt
javac -d out @sources.txt

java -cp out com.library.Main                 # run the demo
java -cp out com.library.LibraryServiceTest   # run the sanity tests

7. Possible Extensions

  • Add due dates / late fees by extending IssueRecord and the service.
  • Add a Reservation flow for books that are currently issued.
  • Swap InMemoryBookRepository/InMemoryMemberRepository for a JDBC- or file-backed implementation — no changes needed elsewhere, by design.

About

Low-Level Design implementation of a Library Management System in Java, demonstrating OOP and SOLID principles through a layered architecture (Model/Repository/Service). Supports book cataloging, member registration, and issue/return workflows with proper validation and exception handling.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages