Como Migrar de uma Arquitetura de 3 Camadas para uma Arquitetura Limpa

Como Migrar de uma Arquitetura de 3 Camadas para uma Arquitetura Limpa

Migrar de uma arquitetura de 3 camadas para uma arquitetura limpa pode parecer desafiador, mas é um passo importante para melhorar a manutenibilidade, escalabilidade e flexibilidade de um projeto. Enquanto a arquitetura de 3 camadas separa as preocupações de apresentação, lógica de negócios e acesso a dados, a Arquitetura Limpa (ou Clean Architecture) busca uma maior separação de responsabilidades, enfatizando a inversão de dependência, de forma que a lógica central da aplicação (Domínio) não dependa de implementações de infraestrutura.

Neste artigo, exploraremos como realizar essa migração, focando em um exemplo C#/.NET, embora o conceito também possa ser aplicado a outras tecnologias.

Arquitetura de 3 Camadas vs Arquitetura Limpa

Antes de iniciarmos a migração, é importante entender a diferença entre as duas arquiteturas.

  • Arquitetura de 3 camadas: Normalmente consiste em uma Camada de Apresentação (UI), uma Camada de Negócio (lógica de aplicação) e uma Camada de Acesso a Dados. Aqui, a camada de negócio frequentemente se conecta diretamente à camada de dados.

  • Arquitetura Limpa: Baseada no princípio da inversão de dependência, ela separa mais claramente as preocupações em quatro grandes camadas: Domínio, Aplicação, Infraestrutura e Interface de Usuário. A regra de ouro da Arquitetura Limpa é que as dependências devem sempre apontar para o centro, ou seja, as camadas externas dependem das internas, mas nunca o contrário.

A transição entre essas duas arquiteturas pode melhorar o design da aplicação, facilitando a testabilidade e a manutenção.

Configurando os Projetos para Arquitetura Limpa

Para começar, você precisará reorganizar seus projetos de forma que reflitam a separação de responsabilidades da Arquitetura Limpa. Siga estas etapas:

1. Renomeie sua Camada de Acesso a Dados para Camada de Domínio

A Camada de Domínio contém as entidades, regras de negócio e lógica de domínio fundamentais da aplicação. Na Arquitetura de 3 Camadas, a lógica de negócio pode estar misturada à camada de acesso a dados. Na Arquitetura Limpa, ela é movida para o Domínio, com foco em manter a lógica de negócios independente de qualquer infraestrutura ou tecnologia específica.

2. Renomeie sua Camada de Negócio para Camada de Aplicação

A Camada de Aplicação lida com casos de uso específicos e coordena o comportamento do sistema. Ela define interfaces para repositórios e serviços que serão implementados em outras camadas (como a Infraestrutura), mas não contém implementações concretas. Isso permite que a camada de aplicação seja totalmente testável e independente da infraestrutura.

3. Adicione a Camada de Infraestrutura

A Camada de Infraestrutura contém as implementações concretas dos repositórios, serviços de terceiros, contexto de banco de dados, entre outros. Esta camada é onde sua aplicação se conecta ao mundo externo (banco de dados, APIs, etc.), mas essas implementações devem ser abstraídas por interfaces que estão definidas nas camadas mais internas, como o Domínio ou a Aplicação.

4. Atualize as Referências

Na Arquitetura Limpa, as referências entre as camadas devem sempre seguir a regra de dependências apontando para o centro. Uma referência típica seria:

  • Apresentação (UI)AplicaçãoDomínio
  • InfraestruturaAplicação

Ou seja, a UI depende da aplicação, que por sua vez depende do domínio. A infraestrutura, que implementa detalhes como o acesso ao banco de dados, também depende da aplicação, mas a aplicação nunca deve depender diretamente da infraestrutura.

Movendo o Contexto do Banco de Dados

Na arquitetura de 3 camadas, o contexto de banco de dados (ex. DbContext no Entity Framework) costuma estar na camada de acesso a dados. Em uma Arquitetura Limpa, o contexto de banco de dados deve ser movido para a Camada de Infraestrutura, pois trata-se de um detalhe de implementação. A lógica de negócios e as regras associadas ao comportamento do domínio permanecem na Camada de Domínio.

  • Infraestrutura: Implementa o DbContext, repositórios e quaisquer interações diretas com o banco de dados.
  • Domínio: Contém as entidades e objetos de valor (sem dependências de infraestrutura).

Implementando o Repositório

Na Camada de Aplicação, você define interfaces para os repositórios. Por exemplo, pode-se definir uma interface IProductRepository na camada de aplicação:

public interface IProductRepository
{
Task<Product> GetByIdAsync(int id);
Task<IEnumerable<Product>> GetAllAsync();
// Outros métodos...
}

A implementação concreta desta interface será feita na Camada de Infraestrutura. A inversão de dependência garante que a aplicação possa funcionar com qualquer implementação de repositório, tornando mais fácil mudar de um banco de dados SQL para NoSQL, por exemplo, sem alterar o restante do código.

public class ProductRepository : IProductRepository
{
private readonly ApplicationDbContext _context;

public ProductRepository(ApplicationDbContext context)
{
_context = context;
}

public async Task<Product> GetByIdAsync(int id)
{
return await _context.Products.FindAsync(id);
}

public async Task<IEnumerable<Product>> GetAllAsync()
{
return await _context.Products.ToListAsync();
}
}

Consumindo o Repositório na Camada de Aplicação

Uma vez que o repositório foi implementado na camada de infraestrutura, você pode consumi-lo na camada de aplicação por meio da injeção de dependência. A Camada de Aplicação deve depender apenas de interfaces, não de implementações concretas.

Exemplo de um caso de uso que consome o repositório:

public class GetProductByIdQueryHandler
{
private readonly IProductRepository _productRepository;

public GetProductByIdQueryHandler(IProductRepository productRepository)
{
_productRepository = productRepository;
}

public async Task<ProductDto> Handle(int productId)
{
var product = await _productRepository.GetByIdAsync(productId);
return new ProductDto(product);
}
}

Atualizando Nomes e Referências

Durante a migração, é crucial atualizar os nomes dos arquivos, namespaces e referências de projetos para seguir a nova organização. Isso inclui:

  • Renomear Data Access Layer (DAL) para Infraestrutura.
  • Atualizar a camada de negócio para ser a Aplicação, que define interfaces e casos de uso.
  • Verificar se o registro de serviços no Startup.cs (ou Program.cs) está correto, especialmente para a injeção de dependência entre as camadas.

Lembre-se de recompilar o projeto após cada modificação significativa para garantir que não haja erros ou referências quebradas.

Conclusão

Migrar de uma arquitetura de 3 camadas para uma Arquitetura Limpa pode parecer uma tarefa desafiadora no início, mas o processo pode ser simplificado ao seguir os princípios de inversão de dependência e separação clara de responsabilidades. A reorganização das camadas melhora a manutenibilidade do sistema, permitindo uma maior flexibilidade ao adicionar ou modificar funcionalidades no futuro.

Conteúdo Relacionado

Retour au blog

Laisser un commentaire

Veuillez noter que les commentaires doivent être approuvés avant d'être publiés.