AULA 18 MÓDULO 5 spec-kit ⏱ 90 min

Spec-Kit: Revisão de Código

Spec-Kit com 28 critérios de qualidade OO. Revisar código gerado por IA. Identificar violações, propor refatoração. Encerramento do semestre.

Spec-KitSRPrefatoraçãoOCPreviewqualidadeIA

Por que revisar código gerado por IA?

Ferramentas como GitHub Copilot, ChatGPT e Claude geram código Java funcional — mas frequentemente com problemas de design OO. O código roda, mas viola princípios que você passou um semestre aprendendo. Saber identificar esses problemas é diferencial profissional.

⚠️
defeitos típicos de IA
Classe de 400 linhas (viola SRP). ArrayList onde HashMap seria O(1). catch (Exception e) {} vazio. Herança onde composição seria melhor. Atributos public. Sem @Override. Sem validação nos setters.
🎯
objetivo desta aula
Aplicar os 28 critérios do Spec-Kit em código real gerado por IA. Identificar o princípio OO violado. Propor e implementar a refatoração.

Spec-Kit — 28 critérios de qualidade OO

SPEC-KIT — 30 CRITÉRIOS · 1 ponto por ✓ · ≥24 = Excelente
ENCAPSULAMENTO
☐
Todos os atributos são private ou protected?
☐
Setters validam invariantes antes de atribuir?
☐
Nenhum getter retorna referência mutável de coleção interna?
☐
A classe pode ser testada sem acessar campos diretamente?
HERANÇA
☐
Relação IS-A semântica verdadeira — não apenas conveniência?
☐
@Override em todo método sobrescrito?
☐
super() chamado quando atributos da superclasse são necessários?
☐
Sem herança apenas para reutilizar código (use composição)?
POLIMORFISMO
☐
Código cliente usa supertipo (List, Forma, Pagamento)?
☐
Listas mistas de subtipos processadas uniformemente?
☐
Existem if/else que poderiam ser substituídos por polimorfismo?
☐
instanceof usado com moderação — evitado onde polimorfismo resolve?
ABSTRAÇÕES E INTERFACES
☐
Dependências de interfaces, não de classes concretas?
☐
Classes abstratas apenas quando há implementação parcial real?
☐
Interfaces coesas e pequenas — Segregação de Interface (ISP)?
☐
Nenhuma classe faz mais de uma coisa — Single Responsibility?
COLEÇÕES — GAP DE MEMÓRIA
☐
ArrayList: operação dominante é acesso por índice — não remoção no meio?
☐
LinkedList: inserção/remoção nas pontas é o padrão dominante?
☐
HashMap: acesso por chave com O(1) médio é o que se precisa?
☐
TreeMap/Set: ordenação natural necessária (O log n) — não só comodidade?
☐
Generics usados corretamente — sem raw types (List sem tipo)?
☐
Retorna interface (List, Map) em vez do tipo concreto (ArrayList)?
EXCEÇÕES
☐
Exceções específicas, não Exception genérica capturada?
☐
Nenhum catch vazio — exception não engolida silenciosamente?
☐
finally ou try-with-resources para fechar recursos?
☐
Exceções customizadas com mensagem clara e contexto de domínio?
QUALIDADE GERAL
☐
Métodos com menos de 20 linhas?
☐
Nomes de classe são substantivos, métodos são verbos?
☐
Nenhuma variável com nome de 1 letra (exceto loops simples)?
☐
JavaDoc nos métodos públicos?

Prática: analisar código gerado por IA

A turma recebe 3 trechos de código Java gerado por IA com problemas propositais. Cada grupo aplica o Spec-Kit e apresenta a refatoração.

EXEMPLOS DE PROBLEMAS TÍPICOS DE IA
❶
Classe SistemaTudo com 500 linhas: processa pagamento, envia email, atualiza estoque, gera relatório. Viola SRP.
❷
List produtos para buscar por ID em loop. HashMap resolveria em O(1).
❸
catch (Exception e) { } vazio. Erro engolido silenciosamente — impossível depurar.
❹
GerenciadorVeiculoCarro extends GerenciadorVeiculoBase apenas para reutilizar um método — não IS-A.
java
// Código gerado por IA com problemas — ANTES da revisão
// Pontuação Spec-Kit: ~10/28. Identifique todos os problemas!

public class Sistema {                    // ❌ SRP — faz tudo
    public String nome;               // ❌ atributo public
    public ArrayList<String> itens; // ❌ raw + tipo concreto

    public void processar(String tipo) {
        if (tipo.equals("pagamento")) {  // ❌ if/else — use polimorfismo
            // lógica de pagamento
        } else if (tipo.equals("estoque")) {
            // lógica de estoque
        }
    }

    public String buscarItem(String id) {
        for (String s : itens)         // ❌ O(n) — use HashMap
            if (s.startsWith(id)) return s;
        return null;
    }

    public void salvar() {
        try { /* escreve arquivo */ }
        catch (Exception e) {}        // ❌ catch vazio!
    }
}

// APÓS revisão com Spec-Kit — versão corrigida:
public class CatalogoItens {             // ✅ nome descreve responsabilidade
    private Map<String, Item> indice;   // ✅ private, Map, generic

    public CatalogoItens() {
        this.indice = new HashMap<>();    // ✅ HashMap para O(1)
    }

    public Optional<Item> buscar(String id) {
        return Optional.ofNullable(indice.get(id)); // ✅ sem null
    }

    public void salvar() throws IOException { // ✅ declara exceção
        /* escreve arquivo */                   // ✅ não engole
    }
}
☕
quiz · aula 18
Teste seus conhecimentos em Java
0/3 respondidas
QUESTÃO 01
No código com problema, por que usar HashMap em vez de iterar a List?
QUESTÃO 02
O que torna catch (Exception e) {} um problema grave?
QUESTÃO 03
Qual princípio SOLID a classe Sistema (que processa pagamento, estoque e email) viola?
0/3