.NET - Domain-Driven Design e Onion Architecture
Neste artigo vamos tratar dos conceitos básicos do Domain-Driven Design(DDD) e a Onion Architecture e como podemos juntar essas duas abordagens. |
O que é Domain-Driven Design ?
Antes de responder a esta pergunta precisamos entender o que é o Domain ou Domínio.
O Domain ou domínio é uma esfera de conhecimento, e, refere-se ao conhecimento do negócio que o software esta tentando modelar.
O Domain-Drive Design (DDD) é uma abordagem onde o foco principal esta nos valores reais do negócio, no propósito, no objetivo do negócio, mais do que em tecnologias ou frameworks.
Os conceitos de detalhes da tecnologia são importantes mas são um meio para atingir o objetivo do negócio.
E para poder entender e ter uma compreensão clara do negócio e de seu domínio, é essencial adotar uma abordagem colaborativa envolvendo especialistas técnicos e especialistas em domínio, que devem usar a mesma linguagem para uma comunicação eficaz.
Outro ponto importante é reduzir a complexidade usando design orientado a objetos e padrões de design para evitar ter que reinventar a roda.
Assim, três atuações importantes devem existir na abordagem do DDD:
Os
Especialistas em domínio são as pessoas que
conhecem as regras de negócios. Eles podem ser gerentes de contabilidade,
especialistas em marketing, cozinheiros, garçons, etc. Eles podem ou não ter
qualquer conhecimento em tecnologia.
Os Especialistas Técnicos são as pessoas
responsáveis por traduzir o conhecimento dos especialistas do domínio em
software. Para que essa comunicação seja eficaz, é importante usar uma linguagem
comum entre especialistas técnicos e especialistas no domínio. Chamamos isso de
linguagem comum ou linguagem onipresente.
A Linguagem Ubíqua, que deve ser utilizada em todas
as formas de comunicação, desde reuniões e documentação até o código-fonte,
tornando-se o modelo de domínio implementado no código.
Outro conceito importante é definir o limite de atuação de um domínio que é conhecido como Bounded Context.
Bounde Context
Ao usar uma
linguagem onipresente, cada termo (embora semelhante) deve ter apenas um
significado. Ao contrário da linguagem humana, onde as palavras podem significar
coisas diferentes dependendo do contexto, o software não lida bem com a
ambigüidade.
Para lidar com isso, o DDD requer que cada idioma pertença a um contexto de
aplicativo. Esse contexto é chamado de Bounded Context ou contexto limitado. Ele
define um escopo onde uma linguagem onipresente pode ser usada livremente. Fora
dele, os termos podem ter outros significados.
Como no DDD a linguagem é o modelo e vice-versa, cada
Bounded Context define o escopo da aplicação de um modelo específico. Ou
seja, um modelo só é válido dentro de seu próprio contexto limitado, conforme
mostrado na figura a seguir:
Outro conceito importante usado o DDD é a Architecture Design que refere-se aos estilos de arquitetura usado na implementação do DDD como : Hexagonal, Onion, Layered, CQRS ,etc.
Quando usamos a abordagem do Domain-Driven Design, podemos usar diferentes arquiteturas. Existe, por exemplo, a arquitetura tradicional de três camadas. Essas camadas podem ser divididas em camadas menores. A ideia básica é ter a camada de apresentação na parte superior, a camada de negócios/domínio no meio e a camada de acesso a dados na parte inferior.
Arquitetura em Camadas
Na arquitetura em Camadas a dependência segue o fluxo de cima para baixo onde Presentation Layer depende da camada Business/Domain e esta depende da camada Data Access Layer.
Onion Architecture
A Onion Architecture é uma arquitetura que fornece uma alternativa robusta para criar aplicativos para uma melhor testabilidade, manutenção e confiabilidade nas infraestruturas como bancos de dados e serviços.
A Onion Architecture é baseada no princípio de inversão de controle. Ela é composta de várias camadas concêntricas que fazem interface umas com as outras em direção ao núcleo. Essa arquitetura não depende da camada de dados, como nas arquiteturas multicamadas tradicionais, mas sim do modelo de domínio.
Podemos encontrar
alguns conceitos de Domain-Driven Design presentes na camada de domínio do Onion
Architecture, mas é importante destacar que DDD e Onion Architecture não são
necessariamente a mesma coisa. Podemos usar Onion sem usar DDD.
O desenho acima é simplificado. Existem outras representações da Onion
Architecture que apresentam camadas adicionais, que podem ser subdivididas em
camadas menores. Mas a Onion Architecture geralmente consiste em quatro camadas:
O Domain-Driven
Design também tem um conceito de serviço ligeiramente diferente do conceito de
serviço de aplicativo. Isso pode causar confusão e nos forçar a sempre
qualificar com "Estou me referindo ao serviço de aplicativo" ou "Estou me
referindo ao serviço de domínio". Portanto, é mais simples nomear a API da
camada de serviço do aplicativo, que também descreve melhor o que essa camada
representa.
A seta apontando da camada de infraestrutura para a camada central representa o
fato de que cada camada pode ver as camadas subjacentes, mas as camadas mais
internas não têm visibilidade ou conhecimento das camadas externas.
A seguir vamos descrever resumidamente cada uma das camadas ou círculos concêntricos:
Core Domain
Quando usamos a Onion Architecture, começamos com a camada central, o núcleo. Mantemos todos os objetos de domínio que têm valor comercial no núcleo. Nunca devemos incluir conceitos tecnológicos como banco de dados, REST ou SQL. A camada central, sendo a camada central, nem sabe que seu domínio, API e infraestrutura existem.
Domain Services
A camada de Domain Services é onde todas as regras de negócios existem. Ao controlar o domínio por meio da API e inserir toda a lógica de negócios dentro do domínio, temos um aplicativo portátil.
API
Usamos a API para nos comunicarmos com o domínio. Para isso, devemos expor apenas objetos imutáveis, evitando o uso indevido da API para obter acesso ao domínio. Se retornarmos objetos mutáveis por meio da API, as pessoas que usam o código podem obter acesso aos componentes do domínio que não pretendemos expor. Embora a API tenha acesso ao Domain Services ao Core Domain, ela não sabe nada sobre a Infraestrutura.
Infrastructure
Esta é a camada mais externa. Inclui adaptadores para bancos de dados, UI, serviços externos como RESTful, etc. Ela tem acesso a todas as áreas da API, Domínio e Core, embora geralmente a maioria das operações que acessam o Domínio devam fazê-lo por meio da API. A exceção a isso seria algo como interfaces de domínio que contêm implementações de infraestrutura.
Você vai encontrar representações com mais ou menos camadas e com outros nomes dado às camadas mas o que sempre deve permanecer é a regra da dependência onde as camadas externas dependem das internas e não o contrário.
Lembrando que as camadas externas são os módulos de baixo nível e as camadas internas são os módulos de alto nível.
Assim o
Domain-Driven Design nos dá uma abordagem mais realista para definir o que
realmente tem valor de negócios e com a Onion Architecture, alcançamos um bom
nível de desacoplamento e podemos abstrair as especificações de tecnologia que
são secundárias para o negócio.
A abstração da infraestrutura torna mais fácil adaptar e adotar novas
tecnologias que melhor atendam aos requisitos do aplicativo.
Na próxima parte do artigo vamos mostrar uma a criação de um projeto ASP .NET Core Web API onde vamos usar a arquitetura em cebola ou Onion Architecture.
"Aquele que diz: "Eu o conheço (Jesus)",
mas não guarda os seus mandamentos, esse é mentiroso, e a verdade não está
nele."
1 João 2:4
Referências:
ASP .NET Core - Implementando a segurança com
ASP.NET Core MVC - Criando um Dashboard .
C# - Gerando QRCode - Macoratti
ASP .NET - Gerando QRCode com a API do Google
ASP .NET Core 2.1 - Como customizar o Identity
Usando o ASP .NET Core Identity - Macoratti
ASP .NET Core - Apresentando o IdentityServer4
ASP .NET Core 3.1 - Usando Identity de cabo a rabo