ae39e45460
NOVAS SKILLS: - next-best-practices v0.1.0 (CLEAN) — Next.js App Router, RSC, caching, data - nextjs-patterns v1.0.0 (CLEAN) — Next.js 15: Server Actions, route handlers - vite v1.0.0 (CLEAN) — env vars, aliases, proxy, CJS compat - uncle-bob v1.0.0 (CLEAN) — Clean Code, SOLID, Clean Architecture - clean-code-review v1.0.0 (CLEAN) — naming, guard clauses, anti-patterns, refactoring - vue v1.0.0 (CLEAN) — Vue framework - vue-composition-api-best-practices v1.0.0 (CLEAN) — composables, Pinia, reactivity BIBLIOTECA INTELIGENTE libs/ (10 dominios, 11 arquivos): - typescript/ — TS safe + generics gotchas - react/ — Next.js App Router + Vite config - vue/ — Composition API + Pinia - linux/ — System diagnostic cheatsheet - database/ — PostgreSQL + MySQL patterns - browser/ — Chromium CLI + E2E testing - security/ — SAST audit (OWASP Top 10) - best-practices/ — Clean Code + SOLID + Clean Architecture - deploy/ — Docker multi-stack + OpenClaw ops - + INDEX.md como guia de navegacao .learnings/ — LRN-20260519-003 criado (biblioteca compartilhada)
121 lines
4.5 KiB
Markdown
121 lines
4.5 KiB
Markdown
# 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<any[]> }
|
|
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)
|