Created
April 1, 2026 10:49
-
-
Save kuntalchandra/07fe15f203e415a90bed0585ded97b5c to your computer and use it in GitHub Desktop.
LLD of LMS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| """ | |
| 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. | |
| """ |
Author
kuntalchandra
commented
Apr 1, 2026
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment