sexta-feira, 16 de abril de 2010

Desvendando o Application Layer

Sabemos que o coração do DDD esta no domínio, dedicamos grande parte da nossa atenção a ele.
Mas gostaria de destacar o papel do application layer e tentar esclarecer algumas confusões sobre ele.

Se você já procurou sobre application layer na internet, que vou chamar aqui de camada de aplicação, com certeza deve ter encontrado várias definições e aplicabilidades diferentes sobre o mesmo, por exemplo, "Application Layer é o mesmo que Service Layer" ou até mesmo relacionar com tecnologias como Web Services e WCF.

Essa confusão de certa forma se justifica pelo fato de que, a responsabilidade da camada de aplicação é de coordenar (ou delegar) os trabalhos realizados pelo domínio, o que é muitas vezes encarado como um façade, o que não esta errado, mas é nessa comparação que começa os problemas, por que o service layer também pode ser um façade.

Devido a esses problemas de definições e comparações, como você não tem um Service Layer em todos os projetos, você pode encarar que talvez não precise de uma camada de aplicação, e é ai que ao meu ver chegamos no ápice do engano.

Para entender bem as diferenças entre eles é necessário destacar uma frase da definição do Evans sobre o application layer: "The tasks this layer is responsible for are meaningful to the business"

Ou seja, não é simplemente chamar métodos de objetos de domínio em uma ordem específica, mas coordenar as tarefas de forma significativa ao negócio. Se você vê semelhanças entre a camada de aplicação e o controller do MVC elas param na palavra coordenar, ok? A controller coordena as interações entre a View e a Model, não é disto que estamos tratamos nesse momento.

Nós, desenvolvedores, geralmente pensamos nas funcionalidades essencialmente como CRUD, fazemos isso por vários motivos, mas talvez o principal se refere a comodidades de interações com banco de dados. O problema desse pensamento é que para o negócio nem sempre o CRUD atende, o cliente não deleta um recebimento ele provavelmente faz um estorno, o cliente não faz um insert de ordem ele abre uma ordem de produção.

A função da camada de aplicação é expor operações realizadas pelo domínio de forma que façam sentido ao domínio, por tanto, se o seu domínio abre uma ordem de produção não faz sentido eu ter SaveProductionOrder() na minha camada de aplicação mas sim OpenProductionOrder().

Isso não quer dizer que os famosos métodos Save, Delete e similires não devam existir na sua camada de aplicação, devido ao fato de que, em alguns casos, não é possível determinar um termo de negócio para essas ações.

Outro ponto importante é a questão da leitura de dados, no DDD nós obtemos os dados através do repositório, faz sentido criar métodos no Application Layer para ler dados? Eu respondo, nenhum. Enquanto em um serviço nós geralmente o utilizamos para operações de leitura e/ou escrita, a camada de aplicação só coordena as operações realizadas pelo meu domínio, quando eu preciso ler alguma coisa eu peço direto para o repositório.

Você deve estar se perguntando: Mas eu preciso de um acesso único ao domínio, não preciso?
Essa busca por um caminho linear é herança do BOLOVO onde você tinha UI > BL > DL > BL > UI.
Essa idéia de que tudo tem que passar pelo domínio gera grandes transtornos para identificar as responsabilidades de cada coisa ou de até mesmo um alto acoplamento entre o domínio e outros recursos da minha aplicação, afinal, tudo passa pelo meu domínio.

No desenho apresentado pelo Evans vemos claramente que isso não é necessário e nem deve ser praticado. Se precisamos de uma funcionalidade que se encontra na camada de infraestrutura podemos acessar diretamente dessa camada.


Concluíndo, apesar das semelhanças que a camada de aplicação tenha com outras funcionalidades precisamos ter em mente que ela precisa estar totalmente comprometida com o negócio.

3 comentários:

Anônimo disse...

Excelente post. Esclareceu uma dúvida que eu tinha mas não encontrava nada sobre isso.

Anônimo disse...

Eduardo boa tarde! Estudo DDD já faz um tempo mas ainda tenho algumas dúvidas...
Imagine a seguinte situação...tenho um domínio sobre operações de crédito...este domínio sabe como uma proposta de crédito deve ser calculada...porém precisa de alguns elementos da infra...logo construi um serviço dentro do dominio para chamar os dados de repositorio e etc...só que também preciso salvar essa proposta calculada para consultas futuras...dai entendi que precisaria criar um serviço para armazenar essa proposta...lendo o livro do Evans fica claro que serviço do dominio são para conter regras para o dominio e serviços de aplicação são para coordenar chamadas de diferentes ambientes...gostaria da sua opnião sobre a minha implementação...

Unknown disse...

Primeiramente desculpa pela demora em responder, mas vamos lá.

Na minha opinião você não precisaria criar um outro serviço para salvar o calculo da operação de crédito a não ser que de alguma forma você esteja reutilizando essa funcionalidade em um outro ponto do seu domínio.

Mas de qualquer forma o raciocínio é esse mesmo.