Pular para o conteúdoPular para navegaçãoPular para rodapé
Voltar para o blog
arquiteturaclean-codedesign-patternsbackend

Arquitetura Limpa: Do Dia 1 à Produção

Brizolla Studio
15 de fevereiro de 2024
8 minutos de leitura
arquiteturaclean-codedesign-patternsbackend

Arquitetura Limpa: Do Dia 1 à Produção

Brizolla Studio
15 de fevereiro de 2024
8 minutos de leitura

Arquitetura Limpa: Do Dia 1 à Produção

A diferença entre um projeto que evolui e um que vira um pesadelo de manutenção geralmente começa no primeiro commit. Arquitetura limpa não é sobre frameworks complexos, mas sobre decisões simples que pagam dividendos a longo prazo.

O Custo da Dívida Técnica

Todo projeto acumula dívida técnica. A questão é: você está tomando empréstimos conscientes ou afundando em juros compostos?

// ❌ Dívida técnica: acoplamento forte
class UserController {
  async saveUser(userData: any) {
    // Validação
    if (!userData.email) throw new Error("Email required");

// Salvamento direto no banco await db.users.create(userData);

// Envio de email await emailService.sendWelcome(userData.email);

// Log console.log("User created:", userData.id); } }

// ✅ Arquitetura limpa: responsabilidades separadas class CreateUserUseCase { constructor( private validator: UserValidator, private repository: UserRepository, private emailService: EmailService, private logger: Logger ) {}

async execute(userData: CreateUserRequest): Promise { this.validator.validate(userData);

const user = await this.repository.create(userData); await this.emailService.sendWelcome(user.email); this.logger.info("User created", { userId: user.id });

return user; } } `

Princípios Fundamentais

1. Single Responsibility Principle Cada classe deve ter uma, e somente uma, razão para mudar.

2. Dependency Inversion Dependa de abstrações, não de implementações concretas.

3. Separation of Concerns Mantenha lógica de negócio separada de infraestrutura e apresentação.

Estrutura em Camadas

src/
├── domain/          # Regras de negócio puras
│   ├── entities/
│   ├── repositories/
│   └── services/
├── application/     # Casos de uso
│   └── use-cases/
├── infrastructure/  # Implementações concretas
│   ├── database/
│   ├── external/
│   └── messaging/
└── presentation/    # APIs e UI
    ├── controllers/
    └── dto/

Padrões Práticos

Repository Pattern ```typescript interface UserRepository { create(user: User): Promise<User>; findById(id: string): Promise<User | null>; update(id: string, data: Partial<User>): Promise<User>; }

class PrismaUserRepository implements UserRepository { async create(user: User): Promise { return await prisma.user.create({ data: user }); } // ... } `

Factory Pattern para Configuração ```typescript class DatabaseFactory { static create(type: 'postgres' | 'mysql'): Database { switch (type) { case 'postgres': return new PostgresDatabase(config.postgres); case 'mysql': return new MySQLDatabase(config.mysql); default: throw new Error('Unsupported database type'); } } } ```

Testabilidade como Guia

Se seu código é difícil de testar, provavelmente há um problema de arquitetura.

// ❌ Difícil de testar
class PaymentProcessor {
  async process(payment: Payment) {
    const stripe = new Stripe(process.env.STRIPE_KEY);
    await stripe.charges.create(payment);
  }

// ✅ Fácil de testar class PaymentProcessor { constructor(private paymentGateway: PaymentGateway) {}

async process(payment: Payment) { return await this.paymentGateway.charge(payment); } }

// Teste unitário describe('PaymentProcessor', () => { it('should process payment successfully', async () => { const mockGateway = { charge: jest.fn().mockResolvedValue({ id: '123' }) }; const processor = new PaymentProcessor(mockGateway);

const result = await processor.process(payment);

expect(result.id).toBe('123'); }); }); `

Evolução Controlada

Arquitetura limpa não significa arquitetura imutável. Significa que mudanças são previsíveis e seguras.

Refactoring Seguro 1. Escreva testes primeiro 2. Extraia interfaces 3. Mova implementações 4. Ajuste dependências 5. Remova código antigo

Métricas de Saúde

- Complexidade Ciclomática: < 10 por método - Acoplamento: Mínimo entre camadas - Cobertura de Testes: > 80% em regras de negócio - Duplicação: < 3% de código duplicado

Conclusão

Arquitetura limpa é um investimento, não um custo. O tempo gasto estruturando bem desde o início economiza semanas de refactoring no futuro.

Lembre-se: o melhor código é aquele que outro desenvolvedor (você mesmo daqui a 6 meses) consegue entender e modificar sem medo.

---

Quer aplicar esses padrões no seu projeto? Fale conosco sobre uma consultoria de arquitetura.

Precisa de ajuda para implementar estas soluções?

Nossos artigos são baseados em experiência real em projetos. Vamos conversar sobre como aplicar estes conceitos no seu negócio.

Falar no WhatsApp