Communitygithub.com

Brians-brain/claude-skills

Design vocabulary for crafting "deep modules": small interfaces hiding a lot of behavior behind them. Use this when designing or improving module interfaces, finding places to deepen modules, deciding where to place seams (places where you can change behavior without modifying code), making code more testable or easier for AI to understand, or when other skills need this design vocabulary.

O que é claude-skills?

This skill provides a precise vocabulary for designing deep modules—modules with small interfaces that conceal complex implementations—to improve leverage for callers and locality for maintainers, while making everything testable. It defines and differentiates key terms like Module (any unit with an interface and implementation), Interface (everything a caller must know to use the module correctly), and Seam (a location where behavior can be changed without modifying code). The skill emphasizes that an interface is the testing surface, deletion tests reveal if a module is truly providing leverage, and a single adapter represents a hypothetical seam while two adapters confirm a real seam. It supports any development platform where code design decisions are made, and includes counterexamples of shallow modules, principles like “interface is the testing surface” and “delete the module test,” as well as guidelines for designing for testability (inject dependencies, return results, keep surface area small). This vocabulary is used throughout the Brians-brain/claude-skills ecosystem, with references to DEEPENING.md, DESIGN-IT-TWICE.md for deeper exploration.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Brians-brain/claude-skills/tree/HEAD/codebase-design

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Programação de Código

Comunique-se com o usuário em português. Os termos abaixo são apresentados primeiro em inglês e depois em português na primeira ocorrência; a partir daí, use apenas os termos em português conforme a tabela.

Projetar um deep module: colocar muito comportamento por trás de uma interface pequena, colocado em uma articulação limpa (seam), e testável através dessa interface. Sempre que estiver projetando ou refatorando código, use esta linguagem e estes princípios. O objetivo é: dar alavancagem (leverage) a quem chama, dar localidade (locality) a quem mantém, e tornar tudo facilmente testável.

Glossário

Use os termos a seguir com precisão: não substitua por "componente", "serviço", "API" ou "fronteira". Uma linguagem consistente é o ponto central.

Módulo (Module): Qualquer coisa que tenha uma interface e uma implementação. Deliberadamente sem escala fixa: pode ser uma função, classe, pacote ou uma fatia que atravessa várias camadas. Evite: unidade, componente, serviço.

Interface (Interface): Tudo o que quem chama precisa saber para usar este módulo corretamente: assinatura de tipos, invariantes, restrições de ordem de chamada, padrões de erro, configuração necessária, características de performance. Evite: API, assinatura (muito estreito, refere-se apenas à superfície de tipos).

Implementação (Implementation): O interior do módulo, ou seja, seu corpo de código. Diferente de Adaptador (Adapter): uma coisa pode ser um adaptador pequeno com muita implementação (ex.: um repositório SQLite) ou um adaptador grande com pouca implementação (ex.: um objeto falso em memória). Use "adaptador" ao discutir articulações; caso contrário, use "implementação".

Profundidade (Depth): A alavancagem na interface. Quanto comportamento o chamador (ou teste) consegue usar para cada unidade de interface que aprende. Um módulo com muito comportamento escondido atrás de uma interface pequena é profundo; um módulo cuja interface é quase tão complexa quanto sua implementação é raso.

Articulação (Seam) (Michael Feathers): Um lugar onde você pode mudar o comportamento sem modificar aquele ponto; ou seja, o local da interface do módulo. Onde colocar a articulação é uma decisão de projeto em si, separada do que é colocado atrás dela. Evite: fronteira (confunde com bounded context do DDD).

Adaptador (Adapter): Uma coisa concreta que satisfaz uma interface em uma determinada articulação. Descreve o papel (qual posição ela preenche), não o conteúdo (o que há dentro).

Alavancagem (Leverage): O benefício que o chamador obtém da profundidade. Para cada unidade de interface aprendida, consegue mais capacidade. O valor de uma implementação é recuperado em N pontos de chamada e M testes.

Localidade (Locality): O benefício que o mantenedor obtém da profundidade. Modificações, bugs, conhecimento e validação concentram-se em um só lugar, em vez de espalhados entre os chamadores. Corrige-se uma vez, surte efeito em toda parte.

Profundo vs. Raso

Módulo profundo (Deep module) = interface pequena + implementação vasta:

┌─────────────────────┐
│   Interface pequena │  ← poucos métodos, parâmetros simples
├─────────────────────┤
│                     │
│  Implementação      │  ← lógica complexa escondida
│  profunda           │
│                     │
└─────────────────────┘

Módulo raso = interface grande + implementação magra (evitar):

┌─────────────────────────────────┐
│        Interface grande         │  ← muitos métodos, parâmetros complexos
├─────────────────────────────────┤
│  Implementação fina             │  ← apenas repassa as coisas
└─────────────────────────────────┘

Ao projetar uma interface, pergunte a si mesmo:

  • Consigo reduzir o número de métodos?
  • Consigo simplificar parâmetros?
  • Consigo esconder mais complexidade dentro?

Princípios

  • Profundidade é uma propriedade da interface, não da implementação. Um módulo profundo pode internamente ser composto de peças pequenas, simuláveis (mockáveis) e substituíveis; apenas essas peças não pertencem à interface. Um módulo pode ter articulações internas (implementação privada, para uso próprio em testes) e articulações externas (na interface).
  • Teste de exclusão. Imagine excluir este módulo. Se a complexidade desaparecer, ele é apenas um repassador. Se a complexidade reaparecer em N pontos de chamada, está cumprindo seu papel.
  • Interface é a superfície de teste. Chamadores e testes atravessam a mesma articulação. Se você precisar contornar a interface para testar, muito provavelmente o formato do módulo está errado.
  • Um adaptador representa uma articulação hipotética; dois adaptadores confirmam uma articulação real. Não introduza uma articulação a menos que realmente haja algo que varie em ambos os lados da articulação.

Projetando para Testabilidade

Uma boa interface torna os testes naturais:

  1. Receba dependências, não as crie você mesmo.

    # Testável
    def fetch_alternates(mpn: str, client: PartSearchClient) -> list[Part]: ...
    
    # Difícil de testar
    def fetch_alternates(mpn: str) -> list[Part]:
        client = DistributorClient(api_key=os.environ["DIST_API_KEY"])
    
  2. Retorne resultados, não produza efeitos colaterais.

    # Testável
    def landed_cost(bom: Bom, freight: Freight) -> Money: ...
    
    # Difícil de testar
    def apply_landed_cost(bom: Bom) -> None:
        bom.total += freight_charge
    
  3. Superfície pequena. Quanto menos métodos, menos testes necessários; quanto menos parâmetros, mais simples a preparação do teste.

Relações

  • Um módulo tem exatamente uma interface (a superfície que ele apresenta a chamadores e testes).
  • Profundidade é uma propriedade do módulo, medida pela sua interface.
  • Articulação é o local onde a interface do módulo está.
  • Adaptador está em uma articulação e satisfaz a interface.
  • Profundidade gera alavancagem para chamadores e localidade para mantenedores.

Estruturas Rejeitadas

  • Definir profundidade como a razão entre linhas de implementação e linhas de interface (Ousterhout): Isso recompensa implementações infladas. Usamos "profundidade é alavancagem".
  • Igualar "interface" a Protocol/classe abstrata do Python ou métodos públicos de uma classe: Muito estreito: aqui a interface inclui tudo o que o chamador precisa saber.
  • "Fronteira": Confunde com bounded context do DDD. Use articulação (seam) ou interface.

Leitura Adicional

  • Aprofundando um grupo de módulos sob dependências existentes, veja DEEPENING.md: classificação de dependências, disciplina de articulação e estratégia de teste "substituir em vez de adicionar".
  • Explorando diferentes projetos de interface, veja DESIGN-IT-TWICE.md: despachar múltiplos subagentes em paralelo para projetar interfaces de maneiras radicalmente diferentes e depois compará-las quanto a profundidade, localidade e posição da articulação.

Habilidades Relacionadas