problemmediumood

Object-Oriented Design for a Library Management System

Problem

Design an Object-Oriented Library Management System to manage books, copies (book items), members, checkouts, reservations, renewals, fines, and notifications. The system should support searching the catalog, issuing and returning book items, reserving unavailable copies, enforcing borrowing limits and due dates, and sending notifications for holds and overdue items.

Preserve diagrams and example code from the original notes; the following design strictly uses the existing content and re-organizes it into the canonical OOD template.

Solution

1. Requirements Analysis

Functional Requirements:

  • Search books by title, author, subject, or publication date.
  • Add/remove/update books and book items (copies).
  • Register and manage member accounts and librarian accounts.
  • Check out, return, renew, and reserve book items.
  • Enforce borrowing limits (e.g., max 5 books) and maximum lending period (e.g., 10 days).
  • Calculate and collect fines for late returns.
  • Send notifications when reserved books become available or when items are overdue.

Non-Functional Requirements:

  • Consistency: Accurate tracking of book item state (available/reserved/loaned).
  • Scalability: Efficient catalog search and support many concurrent members.
  • Reliability: Ensure lending and reservation operations are durable and auditable.
  • Extensibility: Support additional media types (ebooks, audiobooks), and integrate barcode scanners.

Constraints and assumptions:

  • Each physical copy is modelled as a BookItem with a unique barcode.
  • Reservations hold until the book is returned; reservation notifications are sent when a reserved copy becomes available.
  • Business rules (e.g., max items and lending days) are configurable via constants.

2. Use Case Diagram

Actors: Librarian, Member, System

Top use cases: Add/Modify Book, Search Catalog, Register/Cancel Membership, Check-out Book, Reserve Book, Renew Book, Return Book

graph TD
    subgraph LibrarySystem
        UC1(Add/Remove/Edit Book)
        UC2(Search Catalog)
        UC3(Register/Cancel Membership)
        UC4(Check-out Book)
        UC5(Reserve Book)
        UC6(Renew Book)
        UC7(Return Book)
    end
    Librarian --> UC1
    Member --> UC2
    Member --> UC4
    Member --> UC5
    Member --> UC6
    Member --> UC7
    System --> UC5
    System --> UC7

Library Management System

3. Class Diagram

Core classes and responsibilities (brief):

  • Library: root entity that contains catalog and physical racks.
  • Book: bibliographic metadata (ISBN, title, authors, format).
  • BookItem: physical copy with barcode and status (available, reserved, loaned, lost).
  • Account / Member / Librarian: user identities and operations they can perform.
  • BookReservation: represents a reservation for a BookItem by a Member.
  • BookLending: represents the checkout instance with due date.
  • Fine: calculate and collect fines for overdue returns.
  • Catalog / Search: indexing and search operations across collections.
  • Notification: handles sending notifications (reserved available, overdue reminders).
classDiagram
    class Library { +String name +Address address }
    class Book { +String ISBN +String title +List<Author> authors +BookFormat format }
    class BookItem { +String barcode +BookStatus status +Date purchaseDate }
    class Account { +int id +AccountStatus status }
    class Member { +int memberId +Date dateOfMembership +int totalCheckedOut }
    class Librarian { }
    class BookReservation { +Date createdOn +ReservationStatus status }
    class BookLending { +Date borrowedOn +Date dueDate +Date returnedOn }
    class Fine { +collectFine(memberId, days) }
    class Catalog { +searchByTitle() +searchByAuthor() }
    class Notification { +sendNotification() }

    Account <|-- Member
    Account <|-- Librarian
    Book "1" -- "1..*" BookItem : copies
    Member "1" -- "0..*" BookReservation : reservations
    BookItem "1" -- "0..*" BookLending : lendings
    BookReservation "1" -- "1" BookItem : for
    BookLending "1" -- "1" BookItem : for

Library Class Diagram

4. Activity Diagrams

Activity: Check-out a book

graph TD
    A[Member searches catalog] --> B[Select BookItem]
    B --> C{Is BookItem reference-only?}
    C -- Yes --> D[Reject checkout]
    C -- No --> E{Has member reached limit?}
    E -- Yes --> F[Reject checkout]
    E -- No --> G[Create BookLending, set due date]
    G --> H[Update BookItem status to LOANED]
    H --> I[Send checkout notification]

Activity: Return a book

graph TD
    R1[Member returns book] --> R2[Check for fines]
    R2 --> R3{Is overdue?}
    R3 -- Yes --> R4[Calculate & collect fine]
    R3 -- No --> R5[Update BookItem status to AVAILABLE]
    R4 --> R5
    R5 --> R6[If reservations exist, notify next member]

Check-out Book Activity Diagram

5. High-Level Code Implementation

Below are skeletons (Python) that follow the original content and the Google style guidelines where practical. Java skeletons can be added on request.

from abc import ABC
from enum import Enum
from dataclasses import dataclass
from datetime import date, datetime
from typing import List, Optional


class BookFormat(Enum):
    HARDCOVER = 1
    PAPERBACK = 2
    AUDIO_BOOK = 3
    EBOOK = 4


class BookStatus(Enum):
    AVAILABLE = 1
    RESERVED = 2
    LOANED = 3
    LOST = 4


class ReservationStatus(Enum):
    WAITING = 1
    PENDING = 2
    CANCELED = 3
    NONE = 4


class AccountStatus(Enum):
    ACTIVE = 1
    CLOSED = 2
    CANCELED = 3
    BLACKLISTED = 4


@dataclass
class Address:
    street: str
    city: str
    state: str
    zip_code: str
    country: str


class Account(ABC):
    def __init__(self, id: int, password: str, person: object,
                 status: AccountStatus = AccountStatus.ACTIVE) -> None:
        self._id = id
        self._password = password
        self._person = person
        self._status = status

    def reset_password(self) -> None:
        pass


class Member(Account):
    def __init__(self, id: int, password: str, person: object,
                 status: AccountStatus = AccountStatus.ACTIVE) -> None:
        super().__init__(id, password, person, status)
        self.date_of_membership: date = date.today()
        self.total_books_checkedout: int = 0

    def reserve_book_item(self, book_item: 'BookItem') -> None:
        pass

    def checkout_book_item(self, book_item: 'BookItem') -> bool:
        # check limits and reservations
        return True


class Book(ABC):
    def __init__(self, ISBN: str, title: str, subject: str, publisher: str,
                 language: str, number_of_pages: int) -> None:
        self._ISBN = ISBN
        self._title = title
        self._subject = subject
        self._publisher = publisher
        self._language = language
        self._number_of_pages = number_of_pages
        self._authors: List[str] = []


class BookItem(Book):
    def __init__(self, barcode: str, is_reference_only: bool, borrowed: bool,
                 due_date: Optional[date], price: float, book_format: BookFormat,
                 status: BookStatus, date_of_purchase: date,
                 publication_date: date, placed_at: str) -> None:
        super().__init__(ISBN="", title="", subject="", publisher="",
                         language="", number_of_pages=0)
        self._barcode = barcode
        self._is_reference_only = is_reference_only
        self._borrowed = borrowed
        self._due_date = due_date
        self._price = price
        self._format = book_format
        self._status = status
        self._date_of_purchase = date_of_purchase
        self._publication_date = publication_date
        self._placed_at = placed_at

    def checkout(self, member_id: int) -> bool:
        if self._is_reference_only:
            return False
        # delegate to BookLending
        return True


class BookReservation:
    def __init__(self, creation_date: datetime, status: ReservationStatus,
                 book_item_barcode: str, member_id: int) -> None:
        self._creation_date = creation_date
        self._status = status
        self._book_item_barcode = book_item_barcode
        self._member_id = member_id

    def fetch_reservation_details(self, barcode: str) -> Optional['BookReservation']:
        return None


class BookLending:
    def __init__(self, creation_date: datetime, due_date: datetime,
                 book_item_barcode: str, member_id: int) -> None:
        self._creation_date = creation_date
        self._due_date = due_date
        self._return_date: Optional[datetime] = None
        self._book_item_barcode = book_item_barcode
        self._member_id = member_id

    @staticmethod
    def lend_book(barcode: str, member_id: int) -> bool:
        return True


class Fine:
    @staticmethod
    def collect_fine(member_id: int, days: int) -> None:
        pass


class Catalog:
    def __init__(self) -> None:
        self._book_titles = {}
        self._book_authors = {}
        self._book_subjects = {}
        self._book_publication_dates = {}

    def search_by_title(self, query: str) -> List[Book]:
        return self._book_titles.get(query, [])

    def search_by_author(self, query: str) -> List[Book]:
        return self._book_authors.get(query, [])

Library UML

References

Comments