Prática: OOP

Esta lição é a prática hands-on da Fase 3, consolidando conhecimentos de OOP através de um sistema de gerenciamento de biblioteca.

Requisitos do Projeto

Projetar um sistema de gerenciamento de biblioteca que suporte:

Design de Classes

Classes de Entidade

JAVA
// Classe Book
public class Book {
    private String isbn;
    private String title;
    private String author;
    private boolean borrowed;
    
    public Book(String isbn, String title, String author) {
        this.isbn = isbn;
        this.title = title;
        this.author = author;
        this.borrowed = false;
    }
    
    // Getters/Setters
    public String getIsbn() { return isbn; }
    public String getTitle() { return title; }
    public String getAuthor() { return author; }
    public boolean isBorrowed() { return borrowed; }
    public void setBorrowed(boolean borrowed) { this.borrowed = borrowed; }
    
    @Override
    public String toString() {
        return String.format("[%s] %s - %s (%s)", isbn, title, author, borrowed ? "Emprestado" : "Disponível");
    }
}

// Classe Reader
public class Reader {
    private String id;
    private String name;
    private List<Book> borrowedBooks;
    
    public Reader(String id, String name) {
        this.id = id;
        this.name = name;
        this.borrowedBooks = new ArrayList<>();
    }
    
    public String getId() { return id; }
    public String getName() { return name; }
    public List<Book> getBorrowedBooks() { return borrowedBooks; }
    
    public void borrowBook(Book book) {
        borrowedBooks.add(book);
    }
    
    public void returnBook(Book book) {
        borrowedBooks.remove(book);
    }
    
    @Override
    public String toString() {
        return name + " (ID:" + id + ", Emprestados:" + borrowedBooks.size() + ")";
    }
}

Classes de Exceção

JAVA
// Exceção de livro já emprestado
public class BookAlreadyBorrowedException extends Exception {
    public BookAlreadyBorrowedException(String message) {
        super(message);
    }
}

// Exceção de livro não emprestado
public class BookNotBorrowedException extends Exception {
    public BookNotBorrowedException(String message) {
        super(message);
    }
}

// Exceção de leitor não encontrado
public class ReaderNotFoundException extends Exception {
    public ReaderNotFoundException(String message) {
        super(message);
    }
}

Interfaces

JAVA
// Interface de gerenciamento de livros
public interface BookManager {
    void addBook(Book book);
    void removeBook(String isbn);
    Book findBook(String isbn);
    List<Book> getAllBooks();
}

// Interface de gerenciamento de leitores
public interface ReaderManager {
    void addReader(Reader reader);
    void removeReader(String id);
    Reader findReader(String id);
    List<Reader> getAllReaders();
}

Classe Gerenciadora

JAVA
import java.util.*;

// Classe Library
public class Library implements BookManager, ReaderManager {
    private Map<String, Book> books;
    private Map<String, Reader> readers;
    
    public Library() {
        this.books = new HashMap<>();
        this.readers = new HashMap<>();
    }
    
    // Gerenciamento de livros
    @Override
    public void addBook(Book book) {
        books.put(book.getIsbn(), book);
        System.out.println("Livro adicionado: " + book.getTitle());
    }
    
    @Override
    public void removeBook(String isbn) {
        Book book = books.remove(isbn);
        if (book != null) {
            System.out.println("Livro removido: " + book.getTitle());
        } else {
            System.out.println("Livro não encontrado");
        }
    }
    
    @Override
    public Book findBook(String isbn) {
        return books.get(isbn);
    }
    
    @Override
    public List<Book> getAllBooks() {
        return new ArrayList<>(books.values());
    }
    
    // Gerenciamento de leitores
    @Override
    public void addReader(Reader reader) {
        readers.put(reader.getId(), reader);
        System.out.println("Leitor adicionado: " + reader.getName());
    }
    
    @Override
    public void removeReader(String id) {
        Reader reader = readers.remove(id);
        if (reader != null) {
            System.out.println("Leitor removido: " + reader.getName());
        } else {
            System.out.println("Leitor não encontrado");
        }
    }
    
    @Override
    public Reader findReader(String id) {
        return readers.get(id);
    }
    
    @Override
    public List<Reader> getAllReaders() {
        return new ArrayList<>(readers.values());
    }
    
    // Empréstimo de livro
    public void borrowBook(String isbn, String readerId) 
            throws BookAlreadyBorrowedException, ReaderNotFoundException {
        Book book = books.get(isbn);
        if (book == null) {
            System.out.println("Livro não encontrado");
            return;
        }
        
        if (book.isBorrowed()) {
            throw new BookAlreadyBorrowedException("Livro já emprestado: " + book.getTitle());
        }
        
        Reader reader = readers.get(readerId);
        if (reader == null) {
            throw new ReaderNotFoundException("Leitor não encontrado: " + readerId);
        }
        
        book.setBorrowed(true);
        reader.borrowBook(book);
        System.out.println(reader.getName() + " emprestou " + book.getTitle());
    }
    
    // Devolução de livro
    public void returnBook(String isbn, String readerId) 
            throws BookNotBorrowedException, ReaderNotFoundException {
        Book book = books.get(isbn);
        if (book == null) {
            System.out.println("Livro não encontrado");
            return;
        }
        
        if (!book.isBorrowed()) {
            throw new BookNotBorrowedException("Livro não emprestado: " + book.getTitle());
        }
        
        Reader reader = readers.get(readerId);
        if (reader == null) {
            throw new ReaderNotFoundException("Leitor não encontrado: " + readerId);
        }
        
        book.setBorrowed(false);
        reader.returnBook(book);
        System.out.println(reader.getName() + " devolveu " + book.getTitle());
    }
}

Programa Principal

JAVA
import java.util.Scanner;

public class LibrarySystem {
    private static Library library = new Library();
    private static Scanner scanner = new Scanner(System.in);
    
    public static void main(String[] args) {
        // Inicializar dados
        initData();
        
        // Loop principal
        int choice;
        do {
            showMenu();
            choice = scanner.nextInt();
            scanner.nextLine();  // Consumir nova linha
            
            switch (choice) {
                case 1: listBooks(); break;
                case 2: listReaders(); break;
                case 3: borrowBook(); break;
                case 4: returnBook(); break;
                case 5: addBook(); break;
                case 6: addReader(); break;
                case 0: System.out.println("Adeus!"); break;
                default: System.out.println("Escolha inválida");
            }
        } while (choice != 0);
        
        scanner.close();
    }
    
    private static void initData() {
        library.addBook(new Book("978-7-111-40701-0", "Java Programming", "Bruce Eckel"));
        library.addBook(new Book("978-7-111-21382-6", "Design Patterns", "GoF"));
        library.addBook(new Book("978-7-115-22170-8", "Introduction to Algorithms", "CLRS"));
        
        library.addReader(new Reader("R001", "Alice"));
        library.addReader(new Reader("R002", "Bob"));
    }
    
    private static void showMenu() {
        System.out.println("\n=== Sistema de Gerenciamento de Biblioteca ===");
        System.out.println("1. Ver todos os livros");
        System.out.println("2. Ver todos os leitores");
        System.out.println("3. Emprestar livro");
        System.out.println("4. Devolver livro");
        System.out.println("5. Adicionar livro");
        System.out.println("6. Adicionar leitor");
        System.out.println("0. Sair");
        System.out.print("Digite sua escolha: ");
    }
    
    private static void listBooks() {
        System.out.println("\n--- Lista de Livros ---");
        for (Book book : library.getAllBooks()) {
            System.out.println(book);
        }
    }
    
    private static void listReaders() {
        System.out.println("\n--- Lista de Leitores ---");
        for (Reader reader : library.getAllReaders()) {
            System.out.println(reader);
        }
    }
    
    private static void borrowBook() {
        System.out.print("Digite o ISBN: ");
        String isbn = scanner.nextLine();
        System.out.print("Digite o ID do leitor: ");
        String readerId = scanner.nextLine();
        
        try {
            library.borrowBook(isbn, readerId);
        } catch (BookAlreadyBorrowedException | ReaderNotFoundException e) {
            System.out.println("Erro: " + e.getMessage());
        }
    }
    
    private static void returnBook() {
        System.out.print("Digite o ISBN: ");
        String isbn = scanner.nextLine();
        System.out.print("Digite o ID do leitor: ");
        String readerId = scanner.nextLine();
        
        try {
            library.returnBook(isbn, readerId);
        } catch (BookNotBorrowedException | ReaderNotFoundException e) {
            System.out.println("Erro: " + e.getMessage());
        }
    }
    
    private static void addBook() {
        System.out.print("Digite o ISBN: ");
        String isbn = scanner.nextLine();
        System.out.print("Digite o título: ");
        String title = scanner.nextLine();
        System.out.print("Digite o autor: ");
        String author = scanner.nextLine();
        
        library.addBook(new Book(isbn, title, author));
    }
    
    private static void addReader() {
        System.out.print("Digite o ID do leitor: ");
        String id = scanner.nextLine();
        System.out.print("Digite o nome: ");
        String name = scanner.nextLine();
        
        library.addReader(new Reader(id, name));
    }
}

Exemplo de Saída

TEXT
=== Sistema de Gerenciamento de Biblioteca ===
1. Ver todos os livros
2. Ver todos os leitores
3. Emprestar livro
4. Devolver livro
5. Adicionar livro
6. Adicionar leitor
0. Sair
Digite sua escolha: 1

--- Lista de Livros ---
[978-7-111-40701-0] Java Programming - Bruce Eckel (Disponível)
[978-7-111-21382-6] Design Patterns - GoF (Disponível)
[978-7-115-22170-8] Introduction to Algorithms - CLRS (Disponível)

Digite sua escolha: 3
Digite o ISBN: 978-7-111-40701-0
Digite o ID do leitor: R001
Alice emprestou Java Programming

Destaques do Design

Aspecto Descrição
Encapsulamento Atributos privados, acessados via getters/setters
Herança Herança de interface (BookManager, ReaderManager)
Polimorfismo Referências de interface apontam para implementação
Tratamento de exceções Exceções personalizadas para erros de negócios
Coleções Map para livros e leitores, List para registros de empréstimo

❓ Perguntas Frequentes

P: Como estender o sistema? R: Adicione categorias de livros, histórico de empréstimos, multas de atraso, etc.

P: Como persistir dados? R: Use IO de arquivo ou banco de dados para armazenar dados.

P: Como suportar multi-threading? R: Use sincronização (synchronized) ou coleções concorrentes (ConcurrentHashMap).

📖 Resumo

📝 Exercícios

  1. Estender funcionalidade: Adicione categorias de livros e busca por categoria
  2. Histórico de empréstimos: Registre histórico de empréstimos e suporte visualização
  3. Persistência de dados: Salve dados em arquivo e carregue no início do programa

Próxima Lição

Na próxima lição, passaremos para a Fase 4 e aprenderemos sobre Visão Geral do Framework de Coleções — entendendo o sistema de coleções Java.

100%