Uma das grandes dúvidas quando programando é onde colocar o que. A separação em camadas é muito comum, onde definimos separações um pouco mais claras de código. As camadas mais conhecidas, provavelmente, são as do MVC (Model, View, Controller), onde separamos o que é nossa regra de negócio (model), a interação com a regra de negócio (controller) e a interface externa (view).
Porém, existe uma distinção de camadas um pouco diferente, discutida no livro DDD de Eric Evans e que é bastante útil na definição dos limites do nosso código: Domínio, aplicação e infraestrutura.
Domínio
Essa camada é o centro do nosso código. Onde implementamos as regras gerais, ou “políticas”, como chamada por Uncle Bob (Robert Martin). Um modo bastante facil de resumir essa camada é: a razão do software existir. O que realmente interessa para o negócio é o que está nessa camada, e sem ela, não precisamos do software. Em uma aplicação bancária, as contas, o relacionamento entre elas, as regras para cada operação, são exemplos de domínio.
Um modo como gosto de definir a camada de domínio é: tudo que existe “fisicamente” ou que é desejado para o futuro próximo. E essa distinção é bastante importante em casos como: quando uma compra é feita no meu e-commerce, envio email para o usuário. A compra faz parte do domínio, é o coração do meu negócio, mas e o email? Ele deve fazer parte do meu domínio? Eu enviaria o email mesmo que minha loja fosse física, e não um e-commerce? Se não, o email não faz parte do domínio. Já no caso contrario, o que faz parte é o conceito, no caso, uma notificação ao comprador, e não necessáriamente um email.
Aplicação
Seguindo o exemplo anterior, a camada de aplicação é tudo o que a sua aplicação faz mas não faz parte do domínio. Se o nosso email anterior não faz parte do domínio, ele faz parte da aplicação. O email não é enviado quando minha loja é somente física, mas é enviado quando temos um software, portanto, faz parte da aplicação.
Essa camada deve ser executada com bastante cuidado. É muito fácil errar e incluir conceitos do domínio na camada de aplicação.
Voltando ao MVC, o V e o C fazem parte da aplicação. Aqui se constroi a interação com o domínio, e daqui que partem as chamadas para o domínio e nunca o contrario. É tambem nessa camada que recebemos os inputs dos usuários.
Infraestrutura
Como o próprio nome já diz, essa é a camada responsável por dar suporte as outras duas camadas. É onde controlamos a interação com o “externo”. Aqui onde enviamos efetivamente os emails, fazemos a conexão com o banco de dados, interagimos com APIs.
Na camada de infraestrutura, podemos exemplificar como o framework de escolha. O framework é quem sabe realmente enviar um email, direcionar uma requisição web para um controller, consumir o cache, etc. As demais camadas só fazem referência a essa.
A comunicação
Tão importante quanto a definição e separação dessas camadas é a integração entre elas. Cada uma delas tem um nivel de abstração diferente. Podemos definir esse nivel, de modo simplista, como a distancia entre o código e a sua execução de fato. A infraestrutura está muito mais próxima da realização das tarefas do que o domínio, que só conhece os elementos que a compõe.
Cada camada, só deve conhecer e interagir, com uma camada de nivel maior de abstração. O domínio tem o maior nivel de abstração, seguidos da Aplicação e por ultimo infraestrutura. Sendo assim, o domínio não conhece nada da aplicação e nem da infraestrutura. Porém, a aplicação e infraestrutura conhecem o domínio. Vale ressaltar que, mesmo que a infraestrutura seja o nivel mais baixo de abstração e aplicação esteja “acima”, a infraestrutura pode sim conhecer diretamente o domínio.
E de que vale o domínio se não conhece nenhuma parte da execução? Aqui utilizamos o conceito chamado de Inversão de dependência. Voltando ao exemplo do email na compra efetuada, o domínio sabe que precisa notificar o comprador, mas não precisa saber como. Utilizamos uma interface para ilustrar o conceito de notificação, sem expor os detalhes de implementação, evitando que uma camada de nível mais alto conheça uma camada de nivel mais baix. Podemos ver no diagrama a diferença entre as abordagens. É importante notar a direção das setas.
Lembrando que quando falamos em camadas, estamos falando de arquitetura. Arquitetura é algo abstrato e conceitual, e totalmente diferente do que acontece em tempo de execução. Quando o software está rodando, claro que a camada de domínio estára “conversando” com a infraestrutura. E essa é a beleza das separações. Mesmo que na prática utilizamos a infraestrutura através do domínio, a infraestrutura pode mudar de forma totalmente isolada, sem que o domínio seja afetado.