Menu
Coddy logo textTech

Integração de Tratamento de Exceções

Parte da seção Programação Orientada a Objetos do Journey de Java da Coddy. Lição 82 de 87.

challenge icon

Desafio

Fácil

Vamos tornar seu Sistema de Gerenciamento de Biblioteca mais robusto integrando um tratamento adequado de exceções! Um sistema de biblioteca real precisa lidar elegantemente com condições de erro: o que acontece quando alguém tenta pegar emprestado um livro que não existe ou quando um usuário tenta pegar emprestados mais livros do que o permitido? Você criará exceções personalizadas que fornecem informações significativas para esses cenários.

Você continuará desenvolvendo seu código existente em seis arquivos:

  • Book.java: Mantenha sua classe Book com todas as funcionalidades existentes: isbn, title, author, isAvailable, borrowedBy, getDetails() e os getters/setters apropriados.
  • User.java: Mantenha sua classe User com id, name, o ArrayList borrowedBooks, borrowBook(), returnBook(), getBorrowedCount() e toString().
  • LibraryException.java: Crie uma classe de exceção personalizada base chamada LibraryException que estenda Exception. Essa será a classe pai de todas as exceções específicas da biblioteca. Inclua um construtor que aceite uma mensagem e a passe para a classe pai.
  • BookNotAvailableException.java: Crie uma exceção personalizada que estenda LibraryException. Essa exceção deve ser lançada quando alguém tentar pegar emprestado um livro que já foi emprestado. Inclua um construtor que aceite o ISBN do livro e crie uma mensagem significativa como Book not available: [isbn].
  • Library.java: Atualize sua classe Library para lançar exceções em vez de imprimir mensagens de erro. Modifique o método borrowBook(String userId, String isbn) para:
    • Lançar LibraryException com a mensagem User not found: [userId] se o usuário não existir
    • Lançar LibraryException com a mensagem Book not found: [isbn] se o livro não existir
    • Lançar BookNotAvailableException se o livro já tiver sido emprestado
    • Em caso de sucesso, fazer com que o usuário pegue o livro emprestado e retornar a mensagem de confirmação [userName] borrowed [bookTitle]

    Altere a assinatura do método para throws LibraryException e altere o tipo de retorno para String.

    Mantenha todos os outros métodos (addBook, registerUser, findBookByIsbn, findUserById, returnBook, removeBook, searchByTitle, searchByAuthor, getAvailableBooks) funcionando como antes.

  • Main.java: Demonstre seu tratamento de exceções! Você receberá uma string de comandos separados por vírgulas. Cada comando segue um destes formatos:
    • ADD_BOOK:isbn:title:author
    • REGISTER_USER:id:name
    • BORROW:userId:isbn

    Processe cada comando. Para ADD_BOOK, imprima Added: [title]. Para REGISTER_USER, imprima Registered: [name]. Para comandos BORROW, use um bloco try-catch para tratar as exceções; em caso de sucesso, imprima a mensagem de confirmação; para qualquer LibraryException, imprima Error: [exception message].

    Depois de processar todos os comandos, imprima Operations completed.

Você receberá uma entrada: uma string de comandos separados por vírgulas.

Por exemplo, com a entrada ADD_BOOK:ISBN-001:Clean Code:Robert Martin,REGISTER_USER:U001:Alice,BORROW:U001:ISBN-001,BORROW:U001:ISBN-001,BORROW:U002:ISBN-001, sua saída seria:

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

Observe como as exceções personalizadas fornecem mensagens de erro claras e específicas. O primeiro empréstimo é bem-sucedido, o segundo falha porque o livro já foi emprestado (BookNotAvailableException) e o terceiro falha porque o usuário U002 não existe (LibraryException). Essa abordagem torna seu sistema de biblioteca muito mais informativo e fácil de depurar do que mensagens de erro genéricas!

Experimente você mesmo

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

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Ler os comandos separados por vírgula
        String input = scanner.nextLine();
        String[] commands = input.split(",");
        
        // Criar Library e AdminService
        Library library = new Library();
        AdminService adminService = new AdminService(library);
        
        // Processar cada comando
        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: Use um bloco try-catch para chamar library.borrowBook(userId, isbn)
                // Em caso de sucesso, imprima a mensagem de confirmação retornada
                // Em caso de LibraryException, imprima "Error: " + e.getMessage()
            }
        }
        
        // TODO: Print "Operations completed"
    }
}

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Compilador de Java online