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