Menu
Coddy logo textTech

例外処理の組み込み

CoddyのJavaジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 82/87。

challenge icon

チャレンジ

簡単

適切な例外処理を統合することで、図書館管理システムをより堅牢にしましょう!実際の図書館システムでは、エラー状態を適切に処理する必要があります。存在しない本を借りようとした場合や、ユーザーが許可された数以上の本を借りようとした場合に何が起こるでしょうか?これらのシナリオに対して、意味のあるフィードバックを提供するカスタム例外を作成します。

既存のコードをベースに、6つのファイルにわたって構築を続けます:

  • Book.java: 既存のすべての機能(isbn、title、author、isAvailable、borrowedBy、getDetails()、および適切なゲッター/セッター)を備えた Book クラスを保持します。
  • User.java: id、name、borrowedBooks ArrayList、borrowBook()、returnBook()、getBorrowedCount()、および toString() を備えた User クラスを保持します。
  • LibraryException.java: Exception を継承する LibraryException というベースカスタム例外クラスを作成します。これは、すべての図書館固有の例外の親クラスになります。メッセージを受け取り、それを親クラスに渡すコンストラクタを含めてください。
  • BookNotAvailableException.java: LibraryException を継承するカスタム例外を作成します。この例外は、すでに貸出中の本を誰かが借りようとしたときにスローされる必要があります。本の ISBN を受け取り、"Book not available: " + isbn のような意味のあるメッセージを作成するコンストラクタを含めてください。
  • Library.java: エラーメッセージを印刷する代わりに例外をスローするように Library クラスを更新します。borrowBook(String userId, String isbn) メソッドを以下のように変更してください:
    • ユーザーが存在しない場合、メッセージ "User not found: " + userId を持つ LibraryException をスローする
    • 本が存在しない場合、メッセージ "Book not found: " + isbn を持つ LibraryException をスローする
    • 本がすでに貸出中の場合、BookNotAvailableException をスローする
    • 成功した場合は、ユーザーに本を貸し出し、確認メッセージ userName + " borrowed " + bookTitle を返す

    メソッドのシグネチャを throws LibraryException に変更し、戻り値の型を String に変更します。

    他のすべてのメソッド(addBook、registerUser、findBookByIsbn、findUserById、returnBook、removeBook、searchByTitle、searchByAuthor、getAvailableBooks)は以前と同じように動作させ続けます。

  • Main.java: 例外処理を実演します!カンマ区切りのコマンド文字列を受け取ります。各コマンドは次のいずれかの形式に従います:
    • ADD_BOOK:isbn:title:author
    • REGISTER_USER:id:name
    • BORROW:userId:isbn

    各コマンドを処理します。ADD_BOOK の場合は "Added: " + title を出力します。REGISTER_USER の場合は "Registered: " + name を出力します。BORROW コマンドの場合は、try-catch ブロックを使用して例外を処理します。成功した場合は確認メッセージを出力し、LibraryException が発生した場合は "Error: " + e.getMessage() を出力します。

    すべてのコマンドを処理した後、"Operations completed" を出力します。

1つの入力(カンマ区切りのコマンド文字列)を受け取ります。

例えば、入力が ADD_BOOK:ISBN-001:Clean Code:Robert Martin,REGISTER_USER:U001:Alice,BORROW:U001:ISBN-001,BORROW:U001:ISBN-001,BORROW:U002:ISBN-001 の場合、出力は次のようになります:

Added: Clean Code
Registered: Alice
Alice borrowed Clean Code
Error: Book not available: ISBN-001
Error: User not found: U002
Operations completed

カスタム例外が、明確で具体的なエラーメッセージをどのように提供しているかに注目してください。最初の貸出は成功し、2回目は本がすでに貸出中であるため失敗し(BookNotAvailableException)、3回目はユーザー U002 が存在しないため失敗します(LibraryException)。このアプローチにより、図書館システムは一般的なエラーメッセージよりもはるかに情報量が多く、デバッグが容易になります!

自分で試してみよう

import java.util.Scanner;
import java.util.ArrayList;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // カンマ区切りのコマンドを読み込む
        String input = scanner.nextLine();
        String[] commands = input.split(",");
        
        // LibraryとAdminServiceを作成する
        Library library = new Library();
        AdminService adminService = new AdminService(library);
        
        // 各コマンドを処理する
        for (String command : commands) {
            String[] parts = command.split(":");
            String operation = parts[0];
            
            if (operation.equals("ADD_BOOK")) {
                String isbn = parts[1];
                String title = parts[2];
                String author = parts[3];
                if (adminService.addBook(isbn, title, author)) {
                    System.out.println("Added: " + title);
                }
            } else if (operation.equals("REMOVE_BOOK")) {
                String isbn = parts[1];
                if (adminService.removeBook(isbn)) {
                    System.out.println("Removed: " + isbn);
                } else {
                    System.out.println("Cannot remove: " + isbn);
                }
            } else if (operation.equals("REGISTER_USER")) {
                String id = parts[1];
                String name = parts[2];
                if (adminService.registerUser(id, name)) {
                    System.out.println("Registered: " + name);
                }
            } else if (operation.equals("BORROW")) {
                String userId = parts[1];
                String isbn = parts[2];
                // TODO: try-catchブロックを使用してlibrary.borrowBook(userId, isbn)を呼び出す
                // 成功した場合、返された確認メッセージを表示する
                // LibraryExceptionが発生した場合、"Error: " + e.getMessage()を表示する
            }
        }
        
        // TODO: "Operations completed"を表示する
    }
}

オブジェクト指向プログラミングのすべてのレッスン