Skip to content

Instantly share code, notes, and snippets.

@kuntalchandra
Created April 1, 2026 10:49
Show Gist options
  • Select an option

  • Save kuntalchandra/07fe15f203e415a90bed0585ded97b5c to your computer and use it in GitHub Desktop.

Select an option

Save kuntalchandra/07fe15f203e415a90bed0585ded97b5c to your computer and use it in GitHub Desktop.
LLD of LMS
"""
Use case components
1. Actors
- Member (User)
- Librarian (Admin)
2. Core Requirements (mapped to use-cases)
- Search books
- Issue / Return book
- Reserve book
- Add / Remove / Update book
- Fine calculation
"""
"""
Design approach
Entities (Book, User, Transaction)
Repositories (Storage abstraction)
Services (Business logic)
Managers / Facade (Orchestration layer)
"""
from datetime import datetime, timedelta
from enum import Enum
import uuid
class BookStatus(Enum):
AVAILABLE = "AVAILABLE"
ISSUED = "ISSUED"
RESERVED = "RESERVED"
class UserType(Enum):
MEMBER = "MEMBER"
LIBRARIAN = "LIBRARIAN"
# Entities
class Book:
def __init__(self, isbn, title, author, total_copies):
self.isbn = isbn
self.title = title
self.author = author
self.total_copies = total_copies
self.available_copies = total_copies
def is_available(self):
return self.available_copies > 0
class User:
def __init__(self, user_id, name, user_type: UserType):
self.user_id = user_id
self.name = name
self.user_type = user_type
class Transaction:
def __init__(self, book, user):
self.id = str(uuid.uuid4())
self.book = book
self.user = user
self.issue_date = datetime.now()
self.due_date = self.issue_date + timedelta(days=14)
self.return_date = None
def is_overdue(self):
return datetime.now() > self.due_date
class Reservation:
def __init__(self, book, user):
self.id = str(uuid.uuid4())
self.book = book
self.user = user
self.date = datetime.now()
# Repository layer
class BookRepository:
def __init__(self):
self.books = {}
def add_book(self, book: Book):
self.books[book.isbn] = book
def get_book(self, isbn):
return self.books.get(isbn)
def search(self, keyword):
return [
book for book in self.books.values()
if keyword.lower() in book.title.lower()
or keyword.lower() in book.author.lower()
]
class UserRepository:
def __init__(self):
self.users = {}
def add_user(self, user: User):
self.users[user.user_id] = user
def get_user(self, user_id):
return self.users.get(user_id)
class TransactionRepository:
def __init__(self):
self.transactions = {}
def add(self, txn: Transaction):
self.transactions[txn.id] = txn
def get_user_transactions(self, user_id):
return [t for t in self.transactions.values() if t.user.user_id == user_id]
# Service layer
class BookService:
def __init__(self, book_repo: BookRepository):
self.book_repo = book_repo
def add_book(self, isbn, title, author, copies):
book = Book(isbn, title, author, copies)
self.book_repo.add_book(book)
def search_books(self, keyword):
return self.book_repo.search(keyword)
class TransactionService:
def __init__(self, book_repo, txn_repo):
self.book_repo = book_repo
self.txn_repo = txn_repo
def issue_book(self, isbn, user):
book = self.book_repo.get_book(isbn)
if not book or not book.is_available():
raise Exception("Book not available")
book.available_copies -= 1
txn = Transaction(book, user)
self.txn_repo.add(txn)
return txn
def return_book(self, txn_id):
txn = self.txn_repo.transactions.get(txn_id)
if not txn:
raise Exception("Transaction not found")
txn.return_date = datetime.now()
txn.book.available_copies += 1
fine = self.calculate_fine(txn)
return fine
def calculate_fine(self, txn):
if not txn.return_date:
return 0
delay = (txn.return_date - txn.due_date).days
return max(0, delay * 10) # ₹10 per day
class ReservationService:
def __init__(self):
self.reservations = []
def reserve_book(self, book, user):
reservation = Reservation(book, user)
self.reservations.append(reservation)
return reservation
class LibraryManager:
def __init__(self):
self.book_repo = BookRepository()
self.user_repo = UserRepository()
self.txn_repo = TransactionRepository()
self.book_service = BookService(self.book_repo)
self.txn_service = TransactionService(self.book_repo, self.txn_repo)
self.reservation_service = ReservationService()
def register_user(self, user_id, name, user_type):
user = User(user_id, name, user_type)
self.user_repo.add_user(user)
def search_books(self, keyword):
return self.book_service.search_books(keyword)
def issue_book(self, isbn, user_id):
user = self.user_repo.get_user(user_id)
return self.txn_service.issue_book(isbn, user)
def return_book(self, txn_id):
return self.txn_service.return_book(txn_id)
# Example use cases
if __name__ == "__main__":
manager = LibraryManager()
manager.register_user("u1", "Kuntal", UserType.MEMBER)
manager.book_service.add_book("123", "Clean Code", "Robert Martin", 2)
books = manager.search_books("clean")
print("Search Results:", [b.title for b in books])
txn = manager.issue_book("123", "u1")
print("Issued:", txn.book.title)
fine = manager.return_book(txn.id)
print("Fine:", fine)
"""
Important Notes
This design covers:
Encapsulation → Entities vs Services separation
Single Responsibility → Repo vs Service
Extensibility → Easy to add:
Notification service
Payment service for fines
Scalability thinking:
Repo → DB abstraction
Service → stateless APIs
This aligns with standard LMS modules like catalog, user management, and transaction handling.
"""
@kuntalchandra
Copy link
Copy Markdown
Author

Sequence Diagram — Return Book + Fine Sequence Diagram — Issue Book Flow LLD Class Diagram

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment