Tratar erros com exceções, organizar o código em pacotes, consolidar a modelagem em UML e garantir qualidade com princípios SOLID e testes JUnit.
Programação Orientada a Objetos em Java · Docente: Profa. Andréa Barboza Proto Sardi
Abertura. Módulo de fechamento: do "funciona" ao "funciona bem e com confiança". Exceções, pacotes, UML, SOLID e JUnit transformam o protótipo num software profissional. Aplicamos tudo ao Sistema de Gestão Acadêmica.
Módulo 5 · Abertura
Objetivos de aprendizagem
🛡️Tratar erros
Capturar e lançar exceções com try/catch e throw.
📦Organizar
Estruturar o código em pacotes com package e import.
📐Modelar & projetar
Consolidar UML e conhecer os princípios SOLID.
✅Testar
Escrever testes automatizados introdutórios com JUnit.
Objetivos. Quatro frentes de qualidade. Não são "POO nova", são práticas que tornam o código orientado a objetos confiável e sustentável. Tudo demonstrado na classe Aluno.
Retomada · Situação-problema
Quando o inesperado acontece
Main.java
aluno.lerNota(-5); // nota inválida...
aluno.calcularMedia(0); // divisão por zero!// → o programa QUEBRA na cara do usuário
💥
o problema
Sem tratamento, um erro encerra o programa abruptamente, sem explicação útil.
🎯A solução
Antecipar o que pode dar errado e tratar com exceções — o programa reage com elegância em vez de travar.
Gancho. Retome a validação do Módulo 2 (setter que recusava saldo negativo). Lá imprimíamos uma mensagem; agora vamos sinalizar o erro de forma estruturada com exceções — mais robusto e padrão na indústria.
Conceito 1
Exceções: erros sob controle
Uma exceção é um evento que interrompe o fluxo normal. Em vez de travar, o programa pode capturá-la e reagir.
🔢ArithmeticException
Divisão por zero.
📭NullPointerException
Usar referência null.
📏IndexOutOfBounds
Índice fora do array/lista.
🛡️
objetivo
Transformar uma falha catastrófica em uma situação prevista e tratável.
Exceções. Reencontre velhos conhecidos: NullPointer (Módulo 1), IndexOutOfBounds (Módulo 3). Agora aprendemos a lidar com eles. Exceção = objeto que representa um erro; pode ser capturado e tratado.
Conceito 2 · capturar
try / catch
Main.java
try {
int media = total / qtdProvas; // pode dar erro
} catch (ArithmeticException e) {
System.out.println("Não há provas para calcular a média.");
}
🧯
como ler
try: "tente isto". catch: "se a exceção X acontecer, faça aquilo" — sem travar o programa.
try/catch. O bloco try contém o código "arriscado"; o catch trata o tipo específico de exceção. O programa continua após o catch. Mostre rodando com qtdProvas=0: em vez de stack trace, a turma vê a mensagem amigável.
Conceito 3 · lançar
throw: sinalizando um erro
Aluno.java
public voidlerNota(double nota) {
if (nota < 0 || nota > 10) {
throw newIllegalArgumentException(
"Nota deve estar entre 0 e 10");
}
somaNotas += nota;
}
🚨
encapsulamento + robustez
A própria classe recusa dados inválidos lançando uma exceção. A regra mora no método.
throw. Evolução do setter validado (Módulo 2): em vez de só imprimir, lançamos IllegalArgumentException. Quem chamou decide tratar (try/catch). Isso é robustez de verdade: a classe garante seus invariantes e avisa quem a usa mal.
Conceito 4
Pacotes: organizando o projeto
Um pacote é uma pasta lógica que agrupa classes relacionadas e evita conflitos de nome.
Aluno.java
package modelo;
public classAluno { ... }
Main.java
import modelo.Aluno;
public classMain { ... }
📦
já usamos isso
import java.util.ArrayList; do Módulo 3 importava uma classe do pacote java.util.
Pacotes. package declara a "pasta lógica"; import traz classes de outros pacotes. Conecte com o import de ArrayList. Convenção: nomes em minúsculo, geralmente domínio invertido (br.edu.ifgoiano.modelo). Organiza projetos grandes.
Aplicação · arquitetura
O sistema, organizado
Classes de domínio em modelo; ponto de entrada em app. Cada qual com sua responsabilidade.
🗂️
separação de responsabilidades
Modelo (as entidades) separado da aplicação (o que usa as entidades). Facilita manutenção.
Arquitetura. Mostra como os pacotes refletem camadas: modelo × aplicação. É uma prévia natural de SOLID (cada parte com um propósito). Em projetos reais, ainda há pacotes para serviços, repositórios, etc.
Conceito 5 · modelagem
UML: o mapa do sistema
Diagrama de classes: herança (triângulo), visibilidade (+ − #) e a estrutura inteira num olhar.
🗺️
a UML costura o curso
Anatomia (M1), visibilidade (M2), herança (M4) — tudo aparece no mesmo diagrama.
UML. Consolidação visual: o diagrama de classes reúne o que vimos em todos os módulos. Símbolos +/−/# (visibilidade do M2), triângulo de herança (M4), compartimentos (M1). UML é a linguagem para projetar antes de codificar.
Conceito 6 · boas práticas
SOLID: 5 princípios de bom projeto
①S — Responsabilidade Única
Cada classe deve ter um só motivo para mudar.
②O — Aberto/Fechado
Aberta para extensão, fechada para modificação.
③L — Substituição de Liskov
Uma filha deve poder substituir a mãe sem quebrar.
④⑤I e D
Interfaces pequenas e específicas; dependa de abstrações, não de implementações.
SOLID. Apresente como "regras de bom senso" que evitam código rígido e quebradiço. Não aprofunde cada um — o objetivo é vocabulário e consciência. L conecta com polimorfismo (M4); D e I conectam com interfaces (M4). Aprofundamento fica para disciplinas futuras.
SOLID · exemplo
Responsabilidade Única, na prática
⛔Ruim
Uma classe Aluno que calcula médias, e salva em arquivo, e imprime relatório. Três motivos para mudar.
✅Bom
Aluno cuida do aluno; Relatorio imprime; Repositorio salva. Cada uma com uma responsabilidade.
🎯
benefício
Mudar a impressão não arrisca quebrar o cálculo da média. Código mais fácil de manter e testar.
SRP. O princípio mais imediato para iniciantes. "Classe que faz tudo" é o anti-padrão God Class. Separar responsabilidades também facilita os testes (próximo bloco): dá para testar o cálculo isoladamente.
Conceito 7 · qualidade
Por que testes automatizados?
Testar "na mão" toda vez é lento e falho. Um teste automatizado verifica o código em segundos, sempre.
✓
Confiança — você muda o código e sabe na hora se quebrou algo.
✓
Documentação viva — o teste mostra como a classe deve se comportar.
✓
Regressão — bugs corrigidos não voltam sem aviso.
Testes. Venda a ideia antes da ferramenta: testar manualmente não escala. O teste automatizado é uma "rede de segurança". Especialmente importante depois de refatorar (SOLID) — você precisa garantir que nada quebrou.
assertEquals(esperado, obtido) — se baterem, passa (verde); se não, falha (vermelho).
JUnit. @Test marca um método de teste; assertEquals compara esperado × obtido. Use o exercício de média do Módulo 1 como caso de teste (notas 6,6,6 → 6.0). A IDE roda e mostra verde/vermelho. Introdutório: não aprofunde mocks/fixtures.
JUnit · exceções
Testando o que deve falhar
AlunoTest.java
@TestvoidrejeitaNotaInvalida() {
Aluno a = newAluno();
assertThrows(IllegalArgumentException.class,
() -> a.lerNota(-5)); // esperamos a exceção!
}
🧪
fecha o ciclo
Testamos que a validação por exceção (slide 6) realmente barra a nota inválida.
?
Verificação
Por que testar também os casos que devem dar erro?
Testar erros. Resposta: garantir que as regras de validação funcionam — robustez verificada. assertThrows confirma que lerNota(-5) lança a exceção esperada. Une exceções (slide 6) + testes (slide 13). É o casamento de robustez e qualidade.
Erros frequentes
Onde se tropeça
🤫catch vazio
Capturar a exceção e não fazer nada → o erro some sem ninguém saber.
🎣catch genérico demais
Capturar Exception para tudo esconde bugs reais.
📦package errado
Declaração de package que não bate com a pasta → não compila.
🧪Teste sem assert
Um @Test que roda mas não verifica nada não testa coisa alguma.
Erros. "catch vazio" é o pior hábito — engole erros. Capture exceções específicas. package deve espelhar a estrutura de pastas. E teste sem assert dá falsa sensação de segurança. São lições de maturidade de código.
Prática guiada
Aluno robusto e testado
🎯Construir juntos
1. Faça lerNota lançar IllegalArgumentException para notas fora de 0–10.
2. No main, envolva uma chamada inválida em try/catch e exiba a mensagem.
3. Escreva um @Test com assertEquals para a média e outro com assertThrows para a nota inválida.
🛡️
objetivo
Sair com a classe Aluno validada, tratada e testada — pronta para produção.
Prática guiada. O grande fechamento do projeto evolutivo: o Aluno que nasceu no Módulo 1 agora está encapsulado, em hierarquia, em coleções e — aqui — robusto e testado. Faça ao vivo, mostrando o verde do JUnit.
Exercício autônomo
Sua vez: Conta robusta
📋Requisitos
• Em Conta.saca(), lance uma exceção se o valor for maior que o saldo.
• Organize Conta num pacote modelo e a Main em app.
• Escreva testes JUnit: um saque válido (assertEquals no saldo) e um saque inválido (assertThrows).
!
Entrega
Projeto em pacotes + 2 testes JUnit passando (verde).
Exercício autônomo. Tempo: 30 min. Integra exceções + pacotes + testes na entidade Conta. É a "formatura" do curso: o aluno aplica robustez e qualidade a uma classe que conhece desde o Módulo 1. Recolha as soluções.
Revisão · verificação
Revisão relâmpago
✓
try/catch trata · throw sinaliza erros.
✓
Pacotes organizam o código em camadas.
✓
UML mapeia o sistema; SOLID guia o bom projeto.
✓
JUnit verifica comportamento automaticamente.
?
Questão 1
Qual a diferença entre try/catch e throw?
?
Questão 2
O que diz o princípio da Responsabilidade Única?
?
Questão 3
O que assertEquals verifica?
Revisão. Respostas: (1) catch trata uma exceção; throw a lança/sinaliza. (2) cada classe deve ter um único motivo para mudar. (3) que o valor obtido é igual ao esperado. Ticket de saída do curso.
Síntese do Módulo 5
O que levamos deste módulo
🛡️Robustez
Exceções (try/catch, throw) fazem o programa reagir a erros em vez de travar.
✅Qualidade
Pacotes, UML, SOLID e JUnit tornam o código organizado, bem projetado e confiável.
🎓
você chegou ao fim do curso
Saiu de "o que é uma classe" para um sistema orientado a objetos, robusto e testado.
Síntese do módulo. Robustez + qualidade fecham a jornada técnica. Prepare o slide final de encerramento do curso inteiro.
INSTITUTO FEDERALGoiano · Campus Rio Verde
Fim do curso
Os 4 pilares, dominados
📦Abstração & Encapsulamento
Modelar o mundo e proteger o estado.
🌳Herança & Polimorfismo
Reusar, especializar e flexibilizar.
Da classe Cachorro ao Sistema de Gestão Acadêmica robusto e testado. · Obrigada! — Profa. Andréa Barboza Proto Sardi
Encerramento. Recapitule a jornada: Módulo 0 (ambiente) → M1 (objetos/memória) → M2 (encapsulamento) → M3 (coleções) → M4 (herança/polimorfismo) → M5 (robustez/qualidade). Os quatro pilares da POO foram cobertos e aplicados num projeto único e coerente. Celebre o percurso da turma e indique próximos passos (frameworks, banco de dados, projetos maiores).