Menu
Coddy logo textTech

例外処理の組み込み

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

challenge icon

チャレンジ

簡単

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

既存のコードを6つのファイルにわたって引き続き構築します。

  • Book.java:既存のすべての機能を備えた Book クラスを維持します。isbn、title、author、isAvailable、borrowedBy、getDetails()、および適切な getter/setter を含めます。
  • User.java:id、name、borrowedBooks ArrayList、borrowBook()、returnBook()、getBorrowedCount()、および toString() を備えた User クラスを維持します。
  • LibraryException.javaException を継承する、LibraryException という名前の基底カスタム例外クラスを作成します。これは、すべての図書館固有の例外の親クラスになります。メッセージを受け取り、それを親クラスに渡すコンストラクターを含めます。
  • BookNotAvailableException.javaLibraryException を継承するカスタム例外を作成します。この例外は、すでに借りられている本を誰かが借りようとしたときにスローされます。本の 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: [exception message] を出力します。

    すべてのコマンドを処理した後、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: Print "Operations completed"
    }
}

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

自分で練習してみよう: Javaオンラインコンパイラ