図書館管理システム ハンズオン
目次
システム概要
このハンズオンでは、図書館の基本的な業務をJavaで実装します。
以下の機能を持つシステムを段階的に構築していきます:
- 本の貸出/返却管理
- 会員情報の管理
- 蔵書検索機能
クラス構成図
LibrarySystem
├── Book (書籍クラス)
├── Member (会員クラス)
├── BookManager (蔵書管理クラス)
├── MemberManager (会員管理クラス)
└── LibraryService (図書館サービスクラス)
環境構築
必要な環境:
- Java 11以上
- IDE(Eclipse/IntelliJ IDEA)
- JUnit 5(テスト用)
基本クラスの実装
1. Book クラス
/**
* 図書館の書籍を管理するクラス
* ISBN、タイトル、著者、貸出状況などの情報を保持する
*/
public class Book {
// 書籍を一意に識別するISBNコード
private String isbn;
// 書籍のタイトル
private String title;
// 著者名
private String author;
// 貸出可能かどうかのフラグ
private boolean isAvailable;
// 現在の貸出者のID(貸出中でない場合はnull)
private String borrowedBy;
// 返却期限日
private LocalDate dueDate;
/**
* 書籍の新規作成を行うコンストラクタ
* @param isbn ISBN番号
* @param title 書籍タイトル
* @param author 著者名
*/
public Book(String isbn, String title, String author) {
this.isbn = isbn;
this.title = title;
this.author = author;
this.isAvailable = true; // 新規作成時は貸出可能状態
}
// Getterメソッド
public String getIsbn() { return isbn; }
public String getTitle() { return title; }
public String getAuthor() { return author; }
public boolean isAvailable() { return isAvailable; }
public String getBorrowedBy() { return borrowedBy; }
public LocalDate getDueDate() { return dueDate; }
/**
* 書籍の貸出処理を行う
* @param memberId 貸出を行う会員のID
* @param borrowDays 貸出日数
* @throws IllegalStateException 既に貸出中の場合
*/
public void borrowBook(String memberId, int borrowDays) {
if (!isAvailable) {
throw new IllegalStateException("この本は既に貸し出されています");
}
this.isAvailable = false;
this.borrowedBy = memberId;
this.dueDate = LocalDate.now().plusDays(borrowDays);
}
/**
* 書籍の返却処理を行う
*/
public void returnBook() {
this.isAvailable = true;
this.borrowedBy = null;
this.dueDate = null;
}
}
2. Member クラス
/**
* 図書館の会員を管理するクラス
* 会員情報と貸出中の書籍リストを管理する
*/
public class Member {
// 会員を一意に識別するID
private String memberId;
// 会員の名前
private String name;
// 会員のメールアドレス
private String email;
// 貸出中の書籍のISBNリスト
private List<String> borrowedBooks;
/**
* 会員の新規作成を行うコンストラクタ
* @param memberId 会員ID
* @param name 会員名
* @param email メールアドレス
*/
public Member(String memberId, String name, String email) {
this.memberId = memberId;
this.name = name;
this.email = email;
this.borrowedBooks = new ArrayList<>(); // 空の貸出リストで初期化
}
// Getterメソッド
public String getMemberId() { return memberId; }
public String getName() { return name; }
public String getEmail() { return email; }
public List<String> getBorrowedBooks() { return new ArrayList<>(borrowedBooks); }
/**
* 書籍を借りた際の処理
* @param isbn 借りる書籍のISBN
*/
public void borrowBook(String isbn) {
borrowedBooks.add(isbn);
}
/**
* 書籍を返却した際の処理
* @param isbn 返却する書籍のISBN
*/
public void returnBook(String isbn) {
borrowedBooks.remove(isbn);
}
/**
* 現在借りている本の冊数を返す
* @return 貸出中の書籍数
*/
public int getBorrowedCount() {
return borrowedBooks.size();
}
}
3. BookManager クラス
/**
* 図書館の蔵書全体を管理するクラス
* 書籍の追加、検索、在庫確認などの機能を提供する
*/
public class BookManager {
// ISBNをキーとした書籍のマップ
private Map<String, Book> books;
/**
* BookManagerの初期化を行うコンストラクタ
*/
public BookManager() {
this.books = new HashMap<>();
}
/**
* 新しい書籍を蔵書に追加する
* @param book 追加する書籍オブジェクト
* @throws IllegalArgumentException 既に同じISBNの書籍が存在する場合
*/
public void addBook(Book book) {
if (books.containsKey(book.getIsbn())) {
throw new IllegalArgumentException("この本は既に登録されています: " + book.getIsbn());
}
books.put(book.getIsbn(), book);
}
/**
* ISBNから書籍を検索する
* @param isbn 検索するISBN
* @return 該当する書籍。存在しない場合はnull
*/
public Book findByIsbn(String isbn) {
return books.get(isbn);
}
/**
* キーワードで書籍を検索する
* タイトルまたは著者名に指定したキーワードを含む書籍を返す
* @param keyword 検索キーワード
* @return 検索結果の書籍リスト
*/
public List<Book> searchBooks(String keyword) {
return books.values().stream()
.filter(book -> book.getTitle().contains(keyword) ||
book.getAuthor().contains(keyword))
.collect(Collectors.toList());
}
/**
* 現在貸出可能な書籍のリストを取得する
* @return 貸出可能な書籍のリスト
*/
public List<Book> getAvailableBooks() {
return books.values().stream()
.filter(Book::isAvailable)
.collect(Collectors.toList());
}
/**
* 登録されている全書籍の数を返す
* @return 蔵書数
*/
public int getTotalBookCount() {
return books.size();
}
}
4. MemberManager クラス
/**
* 図書館の会員を管理するクラス
* 会員の追加、検索、削除などの機能を提供する
*/
public class MemberManager {
// 会員IDをキーとした会員のマップ
private Map<String, Member> members;
/**
* MemberManagerの初期化を行うコンストラクタ
*/
public MemberManager() {
this.members = new HashMap<>();
}
/**
* 新しい会員を追加する
* @param member 追加する会員オブジェクト
* @throws IllegalArgumentException 既に同じIDの会員が存在する場合
*/
public void addMember(Member member) {
if (members.containsKey(member.getMemberId())) {
throw new IllegalArgumentException("この会員IDは既に使用されています: " + member.getMemberId());
}
members.put(member.getMemberId(), member);
}
/**
* 会員IDから会員を検索する
* @param memberId 検索する会員ID
* @return 該当する会員。存在しない場合はnull
*/
public Member findById(String memberId) {
return members.get(memberId);
}
/**
* 会員を削除する
* @param memberId 削除する会員のID
* @throws IllegalStateException 貸出中の本がある場合
*/
public void removeMember(String memberId) {
Member member = findById(memberId);
if (member == null) {
throw new IllegalArgumentException("会員が見つかりません: " + memberId);
}
if (!member.getBorrowedBooks().isEmpty()) {
throw new IllegalStateException("貸出中の本があるため削除できません");
}
members.remove(memberId);
}
/**
* 登録されている全会員数を返す
* @return 会員数
*/
public int getTotalMemberCount() {
return members.size();
}
}
5. LibraryService クラス
/**
* 図書館の主要な業務ロジックを提供するサービスクラス
* 書籍の貸出/返却、検索などの機能を統合的に管理する
*/
public class LibraryService {
// 書籍管理用のマネージャー
private BookManager bookManager;
// 会員管理用のマネージャー
private MemberManager memberManager;
// 標準の貸出期間(日数)
private static final int DEFAULT_BORROW_DAYS = 14;
/**
* LibraryServiceの初期化を行うコンストラクタ
*/
public LibraryService() {
this.bookManager = new BookManager();
this.memberManager = new MemberManager();
}
/**
* 書籍の貸出処理を行う
* @param memberId 借りる会員のID
* @param isbn 借りる書籍のISBN
* @throws IllegalArgumentException 会員または書籍が存在しない場合
* @throws IllegalStateException 書籍が貸出中の場合
*/
public void borrowBook(String memberId, String isbn) {
// 会員と書籍の存在確認
Member member = memberManager.findById(memberId);
Book book = bookManager.findByIsbn(isbn);
if (member == null || book == null) {
throw new IllegalArgumentException("会員または書籍が見つかりません");
}
// 貸出可能かの確認
if (!book.isAvailable()) {
throw new IllegalStateException("この本は現在貸出できません");
}
// 貸出処理の実行
book.borrowBook(memberId, DEFAULT_BORROW_DAYS);
member.borrowBook(isbn);
}
/**
* 書籍の返却処理を行う
* @param memberId 返却する会員のID
* @param isbn 返却する書籍のISBN
* @throws IllegalArgumentException 会員または書籍が存在しない場合
* @throws IllegalStateException 別の会員が借りている場合
*/
public void returnBook(String memberId, String isbn) {
// 会員と書籍の存在確認
Member member = memberManager.findById(memberId);
Book book = bookManager.findByIsbn(isbn);
if (member == null || book == null) {
throw new IllegalArgumentException("会員または書籍が見つかりません");
}
// 返却権限の確認
if (!memberId.equals(book.getBorrowedBy())) {
throw new IllegalStateException("この本は別の会員が借りています");
}
// 返却処理の実行
book.returnBook();
member.returnBook(isbn);
}
/**
* キーワードによる書籍検索を行う
* @param keyword 検索キーワード
* @return 検索結果の書籍リスト
*/
public List<Book> searchBooks(String keyword) {
return bookManager.searchBooks(keyword);
}
// Getterメソッド
public BookManager getBookManager() { return bookManager