← → navega · N notas · F tela cheia
Módulo 5 de 5

Robustez e
Qualidade

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 void lerNota(double nota) {
    if (nota < 0 || nota > 10) {
        throw new IllegalArgumentException(
            "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 class Aluno { ... }
Main.java
import modelo.Aluno;

public class Main { ... }
📦
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

▾ GestaoAcademica ▾ modelo Pessoa.java Aluno.java Professor.java ▾ app Main.java
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

Pessoa# nome: String# idade: int Aluno- somaNotas: double+ lerNota(n): void Professor- salario: double+ darAula(): void
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.
Conceito 8

JUnit: @Test e assertEquals

AlunoTest.java
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

class AlunoTest {
    @Test
    void calculaMediaCorretamente() {
        Aluno a = new Aluno();
        a.lerNota(6); a.lerNota(6); a.lerNota(6);
        assertEquals(6.0, a.calcularMedia(3));
    }
}
o coração do teste
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
@Test
void rejeitaNotaInvalida() {
    Aluno a = new Aluno();
    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.
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).
módulos
Nota de apresentação para a docente