Problem Statement
Design a library management system that allows users to search, borrow, and return books. The design should manage book availability, maintain borrower records, and ensure that a book cannot be issued to multiple users at the same time.
Functional Requirements
- The design should support adding multiple books to the library
- Users should be able to search books using title or author
- A user should be able to borrow a book if it is available
- A borrowed book should not be issued to another user
- Users should be able to return borrowed books
- Returned books should become available again
- The design should maintain borrowing records
- The system should track issued and available books
Objects Required
- Book
- Member
- BorrowRecord
- Library
- LibraryManagementSystem
- BookStatus
BookStatus Enum
public enum BookStatus {
AVAILABLE,
ISSUED
}
The BookStatus enum represents the current state of a book.
Using enums prevents invalid status values and keeps the state transitions easy to manage.
Book Class
The Book class represents a single book inside the library.
public class Book {
private String bookId;
private String title;
private String author;
private BookStatus status;
public Book(String bookId,
String title,
String author) {
this.bookId = bookId;
this.title = title;
this.author = author;
this.status = BookStatus.AVAILABLE;
}
public boolean isAvailable() {
return status == BookStatus.AVAILABLE;
}
public void issueBook() {
status = BookStatus.ISSUED;
}
public void returnBook() {
status = BookStatus.AVAILABLE;
}
public String getTitle() {
return title;
}
public String getAuthor() {
return author;
}
}
The constructor initializes the book with its id, title, and author.
Every newly added book starts with the AVAILABLE status.
The isAvailable() method checks whether the book can currently be borrowed.
The issueBook() method updates the status when a member borrows the book.
The returnBook() method marks the book as available again after return.
The getter methods are used during searching and displaying book details.
Member Class
The Member class stores information related to a library user.
public class Member {
private String memberId;
private String name;
public Member(String memberId,
String name) {
this.memberId = memberId;
this.name = name;
}
public String getName() {
return name;
}
}
The constructor initializes member details.
The getName() method is useful while displaying borrowing information.
BorrowRecord Class
The BorrowRecord class maintains borrowing details for issued books.
import java.time.LocalDate;
public class BorrowRecord {
private String recordId;
private Member member;
private Book book;
private LocalDate issueDate;
public BorrowRecord(String recordId,
Member member,
Book book) {
this.recordId = recordId;
this.member = member;
this.book = book;
this.issueDate = LocalDate.now();
}
public void closeRecord() {
book.returnBook();
}
}
The constructor creates a borrowing record and stores the issue date.
The closeRecord() method is called when the member returns the book.
Inside this method, the associated book is marked as available again.
Library Class
The Library class manages all books available in the library.
import java.util.*;
public class Library {
private List<Book> books;
public Library(List<Book> books) {
this.books = books;
}
public List<Book> searchByTitle(
String title) {
List<Book> result =
new ArrayList<>();
for (Book book : books) {
if (book.getTitle()
.equalsIgnoreCase(title)) {
result.add(book);
}
}
return result;
}
public List<Book> searchByAuthor(
String author) {
List<Book> result =
new ArrayList<>();
for (Book book : books) {
if (book.getAuthor()
.equalsIgnoreCase(author)) {
result.add(book);
}
}
return result;
}
}
The constructor initializes the library with all available books.
The searchByTitle() method iterates through all books and returns matching titles.
The searchByAuthor() method searches books written by a specific author.
Keeping search logic inside the library class avoids pushing collection related operations to higher level classes.
LibraryManagementSystem Class
The LibraryManagementSystem class coordinates borrowing and returning operations.
import java.util.*;
public class LibraryManagementSystem {
private Library library;
public LibraryManagementSystem(
Library library) {
this.library = library;
}
public BorrowRecord borrowBook(
Member member,
Book book) {
if (!book.isAvailable()) {
System.out.println(
"Book is already issued"
);
return null;
}
book.issueBook();
return new BorrowRecord(
UUID.randomUUID().toString(),
member,
book
);
}
public void returnBook(
BorrowRecord record) {
record.closeRecord();
System.out.println(
"Book returned successfully"
);
}
}
The constructor initializes the management system with the library object.
The borrowBook() method first checks whether the requested book is available.
If the book is already issued, the borrowing request is rejected immediately.
If the book is available, its status is updated and a borrowing record is created.
The returnBook() method closes the borrow record and marks the book as available again.
Main Class
The Main class demonstrates the complete library borrowing flow.
import java.util.*;
public class Main {
public static void main(String[] args) {
Book book1 = new Book(
"B1",
"Clean Code",
"Robert Martin"
);
Book book2 = new Book(
"B2",
"Design Patterns",
"GoF"
);
Library library =
new Library(
Arrays.asList(book1, book2)
);
LibraryManagementSystem system =
new LibraryManagementSystem(
library
);
Member member =
new Member(
"M1",
"Prasanna"
);
BorrowRecord record =
system.borrowBook(
member,
book1
);
if (record != null) {
System.out.println(
"Book issued successfully"
);
}
system.returnBook(record);
}
}
The main() method starts by creating books and adding them to the library.
A member then borrows one of the available books.
Once the borrowing operation succeeds, the book status changes to issued.
Finally, the book is returned, making it available again for future borrowing.
Comments
Post a Comment