Integracja obsługi wyjątków
Część sekcji Programowanie obiektowe ścieżki Java w Coddy. Lekcja 82 z 87.
Wyzwanie
ŁatwyUlepszmy 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 nazwieLibraryException, która rozszerzaException. 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ącyLibraryException. 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 jakBook 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
LibraryExceptionz komunikatemUser not found: [userId], jeśli użytkownik nie istnieje - Zgłaszała
LibraryExceptionz komunikatemBook 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 LibraryExceptioni zmień typ zwracany naString.Pozostaw wszystkie pozostałe metody (addBook, registerUser, findBookByIsbn, findUserById, returnBook, removeBook, searchByTitle, searchByAuthor, getAvailableBooks) działające jak dotychczas.
- Zgłaszała
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:authorREGISTER_USER:id:nameBORROW:userId:isbn
Przetwórz każde polecenie. Dla ADD_BOOK wyświetl
Added: [title]. Dla REGISTER_USER wyświetlRegistered: [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 dowolnegoLibraryExceptionwyświetlError: [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 completedZwróć 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
1Podstawy programowania obiektowego
Pliki zewnętrzneWprowadzenie do programowania obiektowegoKlasy a obiektySłowo kluczowe thisMetodyPola (atrybuty)Metoda konstruktoraPrzeciążanie konstruktoraPodsumowanie — prosty kalkulator4Dziedziczenie
Podstawy dziedziczenia (extends)Słowo kluczowe superPrzesłanianie metod (@Override)Łańcuch wywołań konstruktorówKlasa ObjectDziedziczenie jedno- i wielopoziomoweDlaczego Java nie obsługuje wielodziedziczenia klasPodsumowanie – hierarchia pracowników7Metody specjalne i klasa Object
Metoda toString()equals() i hashCode()Metoda clone()compareTo() i ComparableInterfejs ComparatorPodsumowanie — własne sortowanie10Obsługa wyjątków w programowaniu obiektowym
Hierarchia klas wyjątkówWłasne wyjątkiBłędy sprawdzane a niesprawdzaneWzorzec try-with-resourcesPodsumowanie – zweryfikowany użytkownik13Projekt: System zarządzania biblioteką
Przegląd projektu i projekt UMLKlasy książki i użytkownikaSystem wypożyczeńFunkcja wyszukiwaniaInterfejs administratoraIntegracja obsługi wyjątkówTestowanie i integracja2Modyfikatory dostępu i enkapsulacja
Przegląd poziomów dostępuMetody pobierające i ustawiająceUkrywanie informacjiSłowo kluczowe finalPodsumowanie — menedżer kont bankowych5Polimorfizm
Podstawy przeciążania metodPrzesłanianie metod (w czasie wykonywania)Rzutowanie w górę i w dółOperator instanceofKlasy i metody abstrakcyjnePowtórka — kalkulator figur8Zaawansowane koncepcje OOP
Kompozycja a dziedziczenieAgregacja a kompozycjaKlasy wewnętrzne, zagnieżdżone i anonimoweEnumy i metody enumówRekordy (Java 16+)Klasy zapieczętowane (Java 17+)11Wzorce projektowe — część 1
Wprowadzenie do wzorców projektowychWzorzec SingletonWzorzec FactoryWzorzec BuilderWzorzec ObserverWzorzec Strategy3Właściwości klas i składowe statyczne
Zmienne instancji a zmienne statyczneMetody statyczneBloki statyczneStałe (static final)Powtórka – Counter i Utility6Interfejsy i klasy abstrakcyjne
Wprowadzenie do interfejsówImplementowanie interfejsówImplementacja wielu interfejsówMetody domyślne i statyczne w interfejsieKlasy abstrakcyjne a interfejsyInterfejsy funkcyjnePodsumowanie — system płatnościPoćwicz samodzielnie: Kompilator Java online