Integración de manejo de excepciones
Parte de la sección Programación Orientada a Objetos del Journey de Java de Coddy. Lección 82 de 87.
Desafío
Fácil¡Hagamos que tu sistema de gestión de biblioteca sea más robusto integrando un manejo adecuado de excepciones! Un sistema de biblioteca real necesita gestionar correctamente las condiciones de error: ¿qué ocurre cuando alguien intenta pedir prestado un libro que no existe o cuando un usuario intenta pedir prestados más libros de los permitidos? Crearás excepciones personalizadas que proporcionen información útil para estos casos.
Seguirás desarrollando tu código existente en seis archivos:
Book.java: Conserva tu clase Book con toda la funcionalidad existente: isbn, title, author, isAvailable, borrowedBy, getDetails() y los getters/setters correspondientes.User.java: Conserva tu clase User con id, name, la ArrayList borrowedBooks, borrowBook(), returnBook(), getBorrowedCount() y toString().LibraryException.java: Crea una clase de excepción personalizada base llamadaLibraryExceptionque extiendaException. Esta será la clase padre de todas las excepciones específicas de la biblioteca. Incluye un constructor que acepte un mensaje y se lo pase a la clase padre.BookNotAvailableException.java: Crea una excepción personalizada que extiendaLibraryException. Esta excepción debe lanzarse cuando alguien intente pedir prestado un libro que ya está prestado. Incluye un constructor que acepte el ISBN del libro y cree un mensaje significativo comoBook not available: [isbn].Library.java: Actualiza tu clase Library para que lance excepciones en lugar de imprimir mensajes de error. Modifica el métodoborrowBook(String userId, String isbn)para:- Lanzar
LibraryExceptioncon el mensajeUser not found: [userId]si el usuario no existe - Lanzar
LibraryExceptioncon el mensajeBook not found: [isbn]si el libro no existe - Lanzar
BookNotAvailableExceptionsi el libro ya está prestado - En caso de éxito, hacer que el usuario pida prestado el libro y devolver el mensaje de confirmación
[userName] borrowed [bookTitle]
Cambia la firma del método a
throws LibraryExceptiony cambia el tipo de retorno aString.Mantén todos los demás métodos (addBook, registerUser, findBookByIsbn, findUserById, returnBook, removeBook, searchByTitle, searchByAuthor, getAvailableBooks) funcionando como antes.
- Lanzar
Main.java: ¡Demuestra tu manejo de excepciones! Recibirás una cadena de comandos separados por comas. Cada comando sigue uno de estos formatos:ADD_BOOK:isbn:title:authorREGISTER_USER:id:nameBORROW:userId:isbn
Procesa cada comando. Para ADD_BOOK, imprime
Added: [title]. Para REGISTER_USER, imprimeRegistered: [name]. Para los comandos BORROW, usa un bloque try-catch para gestionar las excepciones: en caso de éxito, imprime el mensaje de confirmación; ante cualquierLibraryException, imprimeError: [exception message].Después de procesar todos los comandos, imprime
Operations completed.
Recibirás una entrada: una cadena de comandos separados por comas.
Por ejemplo, con la 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, tu salida sería:
Added: Clean Code
Registered: Alice
Alice borrowed Clean Code
Error: Book not available: ISBN-001
Error: User not found: U002
Operations completedObserva cómo las excepciones personalizadas proporcionan mensajes de error claros y específicos. El primer intento de préstamo tiene éxito, el segundo falla porque el libro ya está prestado (BookNotAvailableException) y el tercero falla porque el usuario U002 no existe (LibraryException). ¡Este enfoque hace que tu sistema de biblioteca sea mucho más informativo y fácil de depurar que los mensajes de error genéricos!
Pruébalo tú mismo
import java.util.Scanner;
import java.util.ArrayList;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Lee los comandos separados por comas
String input = scanner.nextLine();
String[] commands = input.split(",");
// Crea Library y AdminService
Library library = new Library();
AdminService adminService = new AdminService(library);
// Procesa 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: Usa un bloque try-catch para llamar a library.borrowBook(userId, isbn)
// En caso de éxito, imprime el mensaje de confirmación devuelto
// En caso de LibraryException, imprime "Error: " + e.getMessage()
}
}
// TODO: Print "Operations completed"
}
}Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de OOP
Archivos externosIntroducción a la OOPClases vs. ObjetosLa palabra clave thisMétodosCampos (Atributos)Método constructorSobrecarga de constructoresResumen - Calculadora simple4Herencia
Herencia básica (extends)La palabra clave superSobrescritura de métodos (@Override)Encadenamiento de constructoresLa clase ObjectHerencia simple y multinivelPor qué no hay herencia múltiple de clasesResumen - Jerarquía de empleados7Métodos especiales y la clase Object
Método toString()equals() y hashCode()Método clone()compareTo() y ComparableInterfaz ComparatorResumen - Ordenamiento personalizado10Manejo de excepciones en POO
Jerarquía de clases de excepcionesExcepciones personalizadasErrores Checked vs UncheckedPatrón Try With ResourcesResumen - Usuario validado13Proyecto: Gestión de biblioteca
Descripción general del proyecto y diseño UMLClases de Libro y UsuarioSistema de préstamosFuncionalidad de búsquedaInterfaz de administradorIntegración de manejo de excepcionesPruebas e integración2Modificadores de acceso y encapsulamiento
Visión general de los niveles de accesoMétodos Getter y SetterOcultamiento de informaciónLa palabra clave finalResumen - Gestor de cuentas bancarias5Polimorfismo
Fundamentos de sobrecarga de métodosSobrescritura de métodos (tiempo de ejecución)Upcasting y DowncastingEl operador instanceofClases y métodos abstractosResumen - Calculadora de figuras8Conceptos avanzados de POO
Composición vs. HerenciaAgregación vs. ComposiciónClases internas, anidadas y anónimasEnums y métodos de EnumRecords (Java 16+)Clases selladas (Java 17+)11Patrones de diseño - Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón BuilderPatrón ObserverPatrón Strategy3Propiedades de clase y miembros estáticos
Variables de instancia vs. estáticasMétodos estáticosBloques estáticosConstantes (static final)Repaso - Contador y utilidad6Interfaces y Clases Abstractas
Introducción a las InterfacesImplementación de InterfacesImplementación de Múltiples InterfacesMétodos Default y Static en InterfacesClases Abstractas vs InterfacesInterfaces FuncionalesResumen - Sistema de Pagos9Genéricos
Introducción a los genéricosClases genéricasMétodos genéricosParámetros de tipo delimitadosComodines (?, extends, super)Resumen - Contenedor genérico12Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón IteratorPractica por tu cuenta: Compilador de Java online