Menu
Coddy logo textTech

Интеграция обработки исключений

Часть раздела Объектно-ориентированное программирование путешествия по Java на Coddy — урок 82 из 87.

challenge icon

Задание

Легко

Давайте сделаем вашу систему управления библиотекой более надежной, интегрировав правильную обработку исключений! Реальная библиотечная система должна изящно обрабатывать ошибочные ситуации — что произойдет, если кто-то попытается взять книгу, которой не существует, или когда пользователь пытается взять больше книг, чем разрешено? Вы создадите пользовательские исключения, которые обеспечат содержательную обратную связь для таких сценариев.

Вы продолжите работу над существующим кодом в шести файлах:

  • Book.java: Сохраните класс Book со всей существующей функциональностью — isbn, title, author, isAvailable, borrowedBy, getDetails() и соответствующими геттерами/сеттерами.
  • User.java: Сохраните класс User с id, name, списком ArrayList borrowedBooks, методами borrowBook(), returnBook(), getBorrowedCount() и toString().
  • LibraryException.java: Создайте базовый класс пользовательского исключения с именем LibraryException, который расширяет Exception. Это будет родительский класс для всех специфичных для библиотеки исключений. Включите конструктор, который принимает сообщение и передает его родительскому классу.
  • BookNotAvailableException.java: Создайте пользовательское исключение, которое расширяет LibraryException. Это исключение должно выбрасываться, когда кто-то пытается взять книгу, которая уже выдана. Включите конструктор, который принимает ISBN книги и создает содержательное сообщение, например Book not available: [isbn].
  • Library.java: Обновите класс Library, чтобы он выбрасывал исключения вместо вывода сообщений об ошибках. Измените метод borrowBook(String userId, String isbn), чтобы он:
    • Выбрасывал LibraryException с сообщением User not found: [userId], если пользователь не существует
    • Выбрасывал LibraryException с сообщением Book not found: [isbn], если книга не существует
    • Выбрасывал 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.

Вы получите один входной параметр: строку команд, разделенных запятыми.

Например, при вводе 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

Обратите внимание, как пользовательские исключения предоставляют четкие и конкретные сообщения об ошибках. Первая выдача проходит успешно, вторая завершается ошибкой, так как книга уже выдана (BookNotAvailableException), а третья — ошибкой, так как пользователь 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"
    }
}

Все уроки раздела Объектно-ориентированное программирование