Eu li recentemente DDD. Quando cheguei a esta seção, fiquei agradavelmente surpreso ao descobrir que descobri a mesma arquitetura de quatro camadas que Evans fez. Como o @lonelybug apontou, a camada do domínio deve ser completamente isolada do resto do sistema. No entanto, algo precisa traduzir valores específicos da interface do usuário (cadeias de consulta, dados POST, sessão etc.) em objetos de domínio. É aqui que a camada do aplicativo entra em cena. Seu trabalho é traduzir entre a interface do usuário, a camada de dados e o domínio, ocultando efetivamente o domínio do resto do sistema.
Agora vejo muitos aplicativos ASP.NET MVC onde quase toda a lógica está nos controladores. Esta é uma tentativa fracassada de implementar a arquitetura clássica de 3 camadas. Os controladores são difíceis de testar por unidade, porque eles têm muitas preocupações específicas da interface do usuário. De fato, escrever um controlador para que ele não se preocupe diretamente com os valores "Contexto Http" é um sério desafio por si só. Idealmente, o controlador deve apenas executar a tradução, coordenar o trabalho e cuspir a resposta.
Pode até fazer sentido validação básica na camada de aplicação. Não há problema em o domínio assumir que os valores inseridos fazem sentido (esse é um ID válido para esse cliente e essa sequência representa uma data / hora). No entanto, a validação envolvendo lógica de negócios (posso reservar uma passagem de avião no passado?) Deve ser reservada para a camada de domínio.
Martin Fowler, na verdade, comenta sobre como a maioria das camadas de domínio é plana atualmente . Mesmo que a maioria das pessoas nem saiba o que é uma camada de aplicativo, ele descobre que muitas pessoas fazem objetos de domínio bastante burros e camadas de aplicativos complexas que coordenam o trabalho dos diferentes objetos de domínio. Eu também sou culpado disso. O importante não é construir uma camada, porque alguns livros lhe pediram. A idéia é identificar responsabilidades e separar nosso código com base nessas responsabilidades. No meu caso, a "camada de aplicação" evoluiu naturalmente à medida que aumentava o teste de unidade.
Partindo dos padrões de design corporativo de Martin Fowler, as camadas mais comuns são:
Apresentação - são visualizações, modelos de apresentação que geram a interface de interação para seu aplicativo (estou usando a interação caso seu aplicativo seja acessado por outros sistemas através de serviços da Web ou RMI, portanto, pode não ser uma interface de usuário). Isso também inclui controladores que decidem como as ações serão executadas e como.
Domínio - é onde residem suas regras e lógica de negócios, seus modelos de domínio são definidos etc.
Fonte de dados - essa é a camada de mapeamento de dados (ORM) e a fonte de dados (banco de dados, sistema de arquivos etc.)
Como você desenha os limites entre as três camadas:
Não coloque lógica específica de apresentação em seus modelos ou objetos de domínio
Não coloque lógica nas suas páginas e controladores, ou seja, lógica para salvar objetos no banco de dados, criar conexões com o banco de dados, etc., o que tornará sua camada de apresentação quebradiça e difícil de testar
Use um ORM que permita dissociar o acesso e as ações da fonte de dados do modelo
Siga o paradigma thin controller - modelo de gordura, os controladores são para controlar o processo de execução que não está sendo executado, mais em http://www.littlehart.net/atthekeyboard/2007/04/27/fat-models-skinny-controllers/ e http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model model, view and controller,
fonte
A camada de domínio modela os negócios do seu aplicativo. Esta deve ser sua interpretação clara de suas regras, sua dinâmica de componentes e contém seu estado a qualquer momento.
A camada de aplicação está "preocupada com" definir os trabalhos necessários para realizar uma determinada tarefa de aplicação. Principalmente, é responsável por determinar o trabalho de domínio necessário e interage com outros serviços (externos ou não).
Por exemplo , meu aplicativo de software financeiro possui uma operação de usuário para alterar o estado de uma entidade modelo (entidade conforme definida em DDD [89]):
Mas, como um processo de aplicação, além de todas as consequências do modelo desta operação, tenho que enviar uma comunicação interna para outros usuários da aplicação. Esse tipo de trabalho é "orquestrado" na camada do aplicativo. Eu não gostaria que minha camada de domínio pensasse em direcionar um serviço de mensagens. (e certamente isso não é uma responsabilidade da camada de apresentação). De qualquer maneira, uma coisa é certa: preciso de uma nova camada, pois minha camada de domínio é sobre o negócio principal e minha camada de apresentação é sobre interpretação de comandos do usuário e apresentação de resultados.
Notas:
fonte
A Camada de Domínio deve ser projetada como uma camada de isolamento, o que significa que a lógica e as regras de negócios não devem ser afetadas com nenhum código (na Camada de Aplicativos, Camada de Apresentação e Camada de Infra-estrutura).
A Camada de Aplicação deve ser projetada para fornecer algumas funções sobre o que uma interface de sistema (aplicativo) (pense como uma API ou RESTful) pode fazer. Por exemplo, os usuários podem efetuar login em um sistema e, nessa ação do aplicativo (login), os códigos da camada de aplicativo serão os códigos do cliente para a Camada de Domínio (ou Camada de Infra-estrutura), na qual recupera o objeto Domínio do usuário e aplica os métodos desse objeto para implementar o método função 'login'.
A Camada de Aplicação também deve ser projetada como uma camada de isolamento, o que significa que o comportamento do aplicativo não deve ser afetado por nenhum código (na Camada de Apresentação, Camada de Domínio e Camada de Infra-estrutura).
fonte
O objetivo da Modelagem Orientada a Domínio é separar o modelo de domínio essencial e fazê-lo existir sem nenhuma dependência de outras camadas e outros problemas de aplicativo.
Isso permite que você se concentre no próprio domínio sem distrações (como a coordenação entre a interface do usuário e os serviços de persistência).
fonte
fonte
A principal razão para essas fronteiras é a separação de preocupações . O código que acessa o armazenamento de dados deve ter que se preocupar apenas em acessar o armazenamento de dados. Não deve ser responsável por impor regras aos dados. Além disso, a interface do usuário deve ser responsável por atualizar os controles na interface do usuário, obtendo valores da entrada do usuário e convertendo-os em algo que a camada de domínio possa usar e nada mais. Ele deve chamar as operações fornecidas pela camada de domínio para executar as ações necessárias (por exemplo, salve este arquivo). Um serviço da web chamado deve ser responsável pela conversão do meio de transmissão para algo que a camada de domínio possa usar e, em seguida, chamar a camada de domínio (a maioria das ferramentas faz muito desse trabalho para você).
Essa separação, quando implementada corretamente, pode oferecer a você a capacidade de alterar partes do seu código sem afetar outros. Por exemplo, talvez a ordem de classificação de uma coleção de objetos retornada precise ser alterada. Como você sabe que a camada responsável pela manipulação de dados (geralmente a camada da lógica de negócios) lida com essas coisas, é possível identificar facilmente onde o código precisa ser alterado. Além de não precisar modificar como é recuperado do armazenamento de dados ou de qualquer aplicativo que utilize o domínio (a interface do usuário e o serviço da web do meu exemplo acima).
O objetivo final é tornar seu código o mais fácil de manter possível.
Como uma observação lateral, algumas coisas não podem ser colocadas em uma camada específica do domínio (por exemplo, log, validação e autorização). Esses itens são comumente referidos como preocupações transversais e, em alguns casos, podem ser tratados como uma camada que permanece por si só e que todas as outras camadas podem ver e usar.
Pessoalmente, acho que a abordagem em camadas está desatualizada e que a abordagem de serviço é melhor. Você ainda tem a linha gritante desenhada na areia sobre quem faz o quê, mas isso não o força a ser tão hierárquico. Por exemplo, um serviço de pedido de compra, um serviço de cobrança e um serviço de remessa, da perspectiva do aplicativo, todos esses serviços representam seu domínio, e o adiamento da responsabilidade que descrevi acima ainda é válido nesse contexto, ele acabou de ser alterado que seu domínio existe em vários locais, utilizando ainda o conceito de separação de preocupações.
fonte