Problem Statement
When designing a library management system, poor class design leads to tightly coupled code, making it hard to maintain or extend. Without clear responsibilities, classes become bloated or overlap, causing bugs and confusion.
Jump into concepts and practice - no test required
┌─────────┐ ┌───────────┐ ┌────────────┐ ┌─────────┐
│ Member │──────▶│ Loan │◀──────│ Book │ │Librarian│
└─────────┘ └───────────┘ └────────────┘ └─────────┘
│ ▲
│ │
└────────────────────────────────────────────────────────┘This diagram shows the relationships: Members borrow Books via Loans, Librarians manage the system, and Loans connect Members and Books.
### Before: Poor class design with mixed responsibilities class Library: def __init__(self): self.books = [] self.members = [] self.loans = [] def add_book(self, book): self.books.append(book) def add_member(self, member): self.members.append(member) def loan_book(self, book, member): if book.available: book.available = False self.loans.append({'book': book, 'member': member}) ### After: Clear class design with responsibilities separated class Book: def __init__(self, title, author): self.title = title self.author = author self.available = True class Member: def __init__(self, name): self.name = name self.loans = [] class Loan: def __init__(self, book, member): self.book = book self.member = member self.active = True book.available = False member.loans.append(self) class Librarian: def __init__(self, name): self.name = name def loan_book(self, book, member): if book.available: return Loan(book, member) else: return None
Book logically holds details about books such as title, author, and ISBN.Member is for library users, Librarian manages operations, and Loan tracks borrowing, so they don't store book details.borrowBook inside the Member class in Python?self as the first parameter to access object data.book parameter after self.class Loan:
def __init__(self, book, member):
self.book = book
self.member = member
loan = Loan('1984', 'Alice')
print(loan.book, loan.member)__init__ assigns book and member to instance variables.loan.book and loan.member outputs the strings '1984' and 'Alice' separated by space.Librarian class:class Librarian:
def __init__(self, name):
self.name = name
def addBook(book):
print(f"Adding {book} to library")self as the first parameter to access instance data.addBook lacks self, so it will cause an error when called on an instance.Book stores book info, Member represents users, Loan tracks borrow records, and Librarian manages library operations.Loan class should handle checking if a book is currently loaned out before allowing borrowing, as it tracks loan records.