# Clean Code & Architecture — Uncle Bob + SOLID > Extracted from: `uncle-bob` v1.0.0 + `clean-code-review` v1.0.0 ## 🧹 Clean Code — Regras Fundamentais ### Naming (nomes são a melhor documentação) | Elemento | Convenção | ❌ Errado | ✅ Certo | |----------|-----------|-----------|--------| | Variáveis | Revelam intenção | `n`, `d`, `tmp` | `userCount`, `elapsed` | | Funções | Verbo + substantivo | `user()`, `calc()` | `getUserById()`, `calculateTotal()` | | Booleanos | Forma de pergunta | `active`, `flag` | `isActive`, `hasPermission`, `canEdit()` | | Constantes | SNAKE_CASE | `max`, `timeout` | `MAX_RETRY_COUNT`, `REQUEST_TIMEOUT_MS` | | Classes | Substantivo | `Manager`, `Data` | `UserRepository`, `OrderService` | > Se precisa de comentário para explicar o nome, o nome está errado. ### Functions — Regras | Regra | Guia | |-------|------| | **Small** | Máx 20 linhas, ideal 5-10 | | **One Thing** | Faz uma coisa, e faz bem | | **One Level** | Um nível de abstração por função | | **Few Args** | Max 3 argumentos, preferir 0-2 | | **No Side Effects** | Não muta entradas inesperadamente | ### Guard Clauses (evitar ninho profundidade) ```ts // ❌ 5 níveis de profundidade function processOrder(order: Order) { if (order) { if (order.items.length > 0) { if (order.total > 0) { ... } } } } // ✅ Guard clauses — zero aninhamento function processOrder(order: Order) { if (!order) return; if (order.items.length === 0) return; if (order.total <= 0) return; // lógica principal aqui } ``` ### SRP — Single Responsibility > Uma classe tem **um** motivo para mudar. Um ator, uma responsabilidade. ### DRY + YAGNI - **DRY**: Não duplique — três instâncias de duplicação é o limite para abstrair - **YAGNI**: Você não vai precisar — não construa features não requisitadas --- ## 🔷 SOLID Principles | Princípio | Regra Curta | |-----------|-------------| | **S** — Single Responsibility | Uma razão para mudar | | **O** — Open/Closed | Aberto para extensão, fechado para modificação | | **L** — Liskov Substitution | Subtipo deve ser substituível pelo seu tipo base | | **I** — Interface Segregation | Muitas interfaces específicas > uma geral | | **D** — Dependency Inversion | Dependa de abstrações, não de concretudes | ### D — Dependency Inversion Exemplo ```ts // ❌ Alto nível depende de baixo nível class ReportGenerator { private db = new MySQLConnection(); // concreto! } // ✅ Depende de abstração interface Database { query(sql: string): Promise } class ReportGenerator { constructor(private db: Database) {} // injetado! } ``` --- ## 🏗️ Clean Architecture — Dependency Rule > Dependências de código apontam **para dentro** — para políticas de mais alto nível. ``` ┌─────────────────────────────────────┐ │ Entities / Domain │ ← Nada depende disto ├─────────────────────────────────────┤ │ Use Cases / Business Logic │ ← Só depende de Entities ├─────────────────────────────────────┤ │ Interface Adapters (Controllers) │ ← Só depende de Use Cases ├─────────────────────────────────────┤ │ Frameworks & Drivers (DB, UI) │ ← Tudo depende para dentro └─────────────────────────────────────┘ ``` ### Regra da Dependência ``` Código de alto nível → abstração → código de baixo nível (não pode depender de detalhes) ``` ### Quando Usar Clean Architecture - Projetos com vida útil esperada > 2 anos - Múltiplas equipes trabalhando no mesmo código - Possibilidade de trocar framework - Regras de negócio complexas ## Code Review Checklist (Clean Code) - [ ] Nomes revelam intenção? - [ ] Funções fazem uma coisa só? - [ ] Sem comentários que só recontam o que o código faz? - [ ] Sem código comentado fora? - [ ] Sem mais de 3 argumentos em qualquer função? - [ ] SRP respeitado? - [ ] DRY aplicado mas sem over-abstração? - [ ] Tratamento de erros centralizado? - [ ] Sem uso de `any`/`as any` sem justificativa? - [ ] O retorno do commit deixa o código melhor do que encontrou? (Boy Scout)