Menu
Coddy logo textTech

Integracja obsługi wyjątków

Część sekcji Programowanie obiektowe ścieżki Java w Coddy. Lekcja 82 z 87.

challenge icon

Wyzwanie

Łatwy

Ulepszmy system zarządzania biblioteką, integrując obsługę wyjątków! Rzeczywisty system biblioteczny musi umieć właściwie obsługiwać błędy: co się stanie, gdy ktoś spróbuje wypożyczyć nieistniejącą książkę albo użytkownik spróbuje wypożyczyć więcej książek, niż mu wolno? Utworzysz własne wyjątki, które będą przekazywać zrozumiałe informacje w takich sytuacjach.

Będziesz dalej rozwijać istniejący kod w sześciu plikach:

  • Book.java: Zachowaj klasę Book ze wszystkimi dotychczasowymi funkcjami: isbn, title, author, isAvailable, borrowedBy, getDetails() oraz odpowiednimi getterami i setterami.
  • User.java: Zachowaj klasę User z polami id i name, tablicą ArrayList borrowedBooks oraz metodami borrowBook(), returnBook(), getBorrowedCount() i toString().
  • LibraryException.java: Utwórz podstawową własną klasę wyjątku o nazwie LibraryException, która rozszerza Exception. Będzie to klasa nadrzędna dla wszystkich wyjątków dotyczących biblioteki. Dodaj konstruktor, który przyjmuje komunikat i przekazuje go do klasy nadrzędnej.
  • BookNotAvailableException.java: Utwórz własny wyjątek rozszerzający LibraryException. Ten wyjątek powinien być zgłaszany, gdy ktoś próbuje wypożyczyć książkę, która jest już wypożyczona. Dodaj konstruktor, który przyjmuje ISBN książki i tworzy zrozumiały komunikat, taki jak Book not available: [isbn].
  • Library.java: Zaktualizuj klasę Library tak, aby zgłaszała wyjątki zamiast wyświetlać komunikaty o błędach. Zmodyfikuj metodę borrowBook(String userId, String isbn), aby:
    • Zgłaszała LibraryException z komunikatem User not found: [userId], jeśli użytkownik nie istnieje
    • Zgłaszała LibraryException z komunikatem Book not found: [isbn], jeśli książka nie istnieje
    • Zgłaszała BookNotAvailableException, jeśli książka jest już wypożyczona
    • W przypadku powodzenia pozwalała użytkownikowi wypożyczyć książkę i zwracała komunikat potwierdzający [userName] borrowed [bookTitle]

    Zmień sygnaturę metody na throws LibraryException i zmień typ zwracany na String.

    Pozostaw wszystkie pozostałe metody (addBook, registerUser, findBookByIsbn, findUserById, returnBook, removeBook, searchByTitle, searchByAuthor, getAvailableBooks) działające jak dotychczas.

  • Main.java: Zademonstruj obsługę wyjątków! Otrzymasz ciąg poleceń rozdzielonych przecinkami. Każde polecenie ma jeden z następujących formatów:
    • ADD_BOOK:isbn:title:author
    • REGISTER_USER:id:name
    • BORROW:userId:isbn

    Przetwórz każde polecenie. Dla ADD_BOOK wyświetl Added: [title]. Dla REGISTER_USER wyświetl Registered: [name]. W przypadku poleceń BORROW użyj bloku try-catch do obsługi wyjątków; w przypadku powodzenia wyświetl komunikat potwierdzający, a w przypadku dowolnego LibraryException wyświetl Error: [exception message].

    Po przetworzeniu wszystkich poleceń wyświetl Operations completed.

Otrzymasz jedno wejście: ciąg poleceń rozdzielonych przecinkami.

Na przykład dla wejścia ADD_BOOK:ISBN-001:Clean Code:Robert Martin,REGISTER_USER:U001:Alice,BORROW:U001:ISBN-001,BORROW:U001:ISBN-001,BORROW:U002:ISBN-001 wynikiem będzie:

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

Zwróć uwagę, że własne wyjątki przekazują jasne, konkretne komunikaty o błędach. Pierwsza próba wypożyczenia kończy się powodzeniem, druga nie powiedzie się, ponieważ książka jest już wypożyczona (BookNotAvailableException), a trzecia nie powiedzie się, ponieważ użytkownik U002 nie istnieje (LibraryException). Dzięki temu system biblioteczny przekazuje znacznie więcej informacji i łatwiej go debugować niż w przypadku ogólnych komunikatów o błędach!

Spróbuj swoich sił

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

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Wczytaj polecenia rozdzielone przecinkami
        String input = scanner.nextLine();
        String[] commands = input.split(",");
        
        // Utwórz Library i AdminService
        Library library = new Library();
        AdminService adminService = new AdminService(library);
        
        // Przetwórz każde polecenie
        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: Użyj bloku try-catch, aby wywołać library.borrowBook(userId, isbn)
                // W przypadku powodzenia wypisz zwrócony komunikat potwierdzający
                // W przypadku LibraryException wypisz "Error: " + e.getMessage()
            }
        }
        
        // TODO: Wypisz "Operations completed"
    }
}

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Java online