Artigo no estilo: Curso

Por que eu devo ler este artigo:Neste artigo abordaremos o desenvolvimento de uma aplicação ASP.NET com a utilização de um padrão de desenvolvimento conhecido como DDD (Domain-Driven Design), que tem por finalidade orientar o desenvolvimento de projetos com base no domínio de nossa aplicação e não nas tecnologias que serão utilizadas para o seu desenvolvimento.

Os principais fatores para a utilização do DDD são a independência de tecnologias e o alinhamento do código com o negócio. Devido a essas razões, é de grande importância a utilização do DDD.

Apresentaremos então a criação de uma estrutura básica para um webservice, apresentando os principais conceitos de utilização do DDD e sua estrutura, onde também usaremos o Entity Framework.

O desenvolvimento de softwares com base na arquitetura em camadas tem sido a norma vigente em projetos corporativos por algum tempo. Desenvolvemos nossas soluções em grupos de responsabilidades como interface do usuário, serviços, acesso a dados, infraestrutura, entre outros.

Podemos ligar essas camadas definindo as referências a elas a partir da camada de serviços. Existem várias maneiras de definir essas camadas e suas referências. As escolhas que fazemos aqui dependem do tipo de projeto que será utilizado, podendo este ser Web, WPF, WCF, games, etc.

É certo que para o desenvolvimento de um software são necessárias habilidades e conhecimentos da equipe técnica responsável pela sua criação, mas além desse ponto, e sendo inclusive mais importante, é necessário ter o conhecimento com relação ao propósito do software, o que quer dizer que precisamos ter o conhecimento do domínio da aplicação.

Este, por sua vez, é obtido através de pessoas especializadas no ramo do negócio para o qual o software será desenvolvido. Esta pessoa tem que estar em trabalho conjunto com a equipe de desenvolvimento para que se tenha a real dimensão do projeto, de seus recursos e das necessidades da empresa.

É aqui onde entra o nosso tema de estudos, o desenvolvimento de aplicações com base no seu domínio, ou mais popularizado como DDD – Domain-Driven Design.

O DDD é um conjunto de princípios e padrões que ajudam os desenvolvedores a manterem a elegância no desenvolvimento dos objetos em seus sistemas. Sendo aplicado de forma correta, ele poderá levar a abstrações de software chamados modelos de domínio, que são responsáveis por encapsular a lógica de negócio da aplicação. Neste artigo falaremos então sobre os conceitos básicos e também sobre os padrões de projetos pertinentes para o DDD.

Ele é uma abordagem de desenvolvimento que abrange três pontos principais, que são a abordagem para o desenvolvimento do software em conjunto, a abordagem sobre as iniciativas estratégicas do negócio, e por fim, atender às exigências técnicas reais do software.

· Abordagem para o desenvolvimento do software – este ponto é responsável pela integração entre a equipe de desenvolvimento e as pessoas que conhecem o domínio do sistema;

· Iniciativas estratégicas – este princípio ajuda a definir as melhores relações interorganizacionais da equipe, fornecendo formas de reconhecimento de possíveis falhas no projeto.

· Atendimento das necessidades do software – nesta etapa é onde são atendidas as exigências técnicas reais do software, utilizando ferramentas de modelagem para analisar e desenvolver as entregas de software executáveis. Estas ferramentas permitem que os desenvolvedores produzam softwares com uma codificação correta do modelo mental dos especialistas de domínio, o que resulta em uma menor margem de erros de interpretação

Quando começamos a pensar sobre as questões referentes às tecnologias, estas de certa forma, tornam-se detalhes de implementação, onde o tipo de implementação exato pode variar. Nós realmente não nos importamos com qual pacote gráfico será utilizado, isso é um detalhe de implementação.

Nós não nos importamos mais com que tecnologia ORM (BOX 1) usamos; isso é um detalhe de implementação. Claro que as preocupações relacionadas com a tecnologia serão aspectos importantes da fase de planejamento, mas não tão importantes como a forma de representar corretamente o nosso negócio no código.

BOX 1. ORM

É uma técnica de programação para conversão e mapeamento de dados entre bancos de dados relacionais e linguagens de programação orientadas a objetos. Elas criam um objeto virtual que representa o banco de dados que poderá ser usado a partir de uma linguagem de programação de forma transparente para o usuário.

Em uma abordagem orientada a tecnologia é dada uma prioridade maior à tecnologia do que ao domínio, onde recaímos a questões como: "Temos de mudar o domínio do cliente, pois sua estrutura não se encaixa com a utilização do LINQ to SQL".

No DDD, a direção é invertida: "Uma parte importante da nossa estrutura de domínio do cliente mudou, por isso precisamos atualizar nossas classes LINQ to SQL em conformidade.". Uma mudança na tecnologia nunca deve forçar uma mudança em seu domínio, pois ele é uma entidade independente que só muda se mudarem suas regras de negócio ou quando descobrimos que nossa lógica de domínio foge do escopo do nosso negócio.

Tenha em mente que não é o número de camadas que torna a nossa solução "moderna". Se aplicarmos corretamente o uso do DDD, então teremos um aplicativo fácil de se trabalhar e aberto a todos os tipos de extensões, mesmo as não pervistas. Este último aspecto é importante manter em mente, pois hoje em dia as expectativas e lista de desejos dos clientes mudam com muita frequência.

Por conta disso, temos praticamente uma atualização do produto quase toda semana, onde trabalhamos em estreita colaboração com o cliente em cada incremento que construímos. Com base nestes produtos incrementais o cliente pode vir com novas exigências e é melhor estarmos preparados para reagir rapidamente.

Nosso propósito aqui será criarmos uma aplicação genérica de webservice, apresentando os principais conceitos de utilização do DDD e sua estrutura. Ao final deste curso teremos uma aplicação base com as seguintes camadas:

· Infraestrutura: oferece serviços de recursos técnicos para acomodar preocupações transversais, como persistência de dados.

· Acesso a dados (repositório): camada de acesso a dados e tecnologia de persistência, como Entity Framework.

· Domínio da aplicação: esta será a camada responsável pelas nossas entidades empresariais e lógica (nosso foco).

· Serviços de aplicativos: é responsável por coordenar as tarefas e delegar trabalho para objetos de domínio. Esta camada não contém lógica de negócio.

· Web: o consumidor final da aplicação, cujo único objetivo é apresentar os dados e receber as requisições do usuário. A implementação dessa camada utilizará a tecnologia WebAPI para que não precisemos perder tempo com estruturação de CSS e HTML.

O DDD define uma série de "blocos" de padrão (Building Blocks) que são utilizados ​​para projetar um domínio. Esses blocos de construção fazem parte de um conceito de linguagens de padrões, os quais descrevem as responsabilidades dos objetos de domínio. Cada um desses blocos tem sua importância, a qual iremos descrever no decorrer do artigo.

Entidades e objetos de valor (Entities e Value Objects)

Os objetos de domínio podem ser divididos em entidades e objetos de valor. Uma entidade é um objeto com uma identificação única. Esta identificação única é a propriedade mais importante de uma entidade, é ela que ajuda a distinguir entre dois objetos idênticos.

Podemos ter duas pessoas com o mesmo nome, mas se os seus IDs são diferentes, então estamos falando de duas pessoas diferentes. Um ID é normalmente um inteiro ou algum outro valor de sequência gerado aleatoriamente com base em algumas propriedades do objeto.

Uma vez que a entidade tenha sido persistida, o seu ID nunca deve mudar, caso contrário podemos perder o controle da mesma.

Por outro lado, um objeto de valor não tem qualquer tipo de identificação. A principal característica que define um objeto de valor é que ele não tem uma identidade. Ele tem por intuito representar algo apenas pela definição de seus atributos.

Dois objetos de valor podem ter atributos idênticos, desta forma, sendo eles idênticos. Um outro aspecto comum aos objetos de valor é que eles devem ser imutáveis, onde uma vez que criados, eles não podem ser alterados.

Às vezes não é fácil decidir se um objeto específico é uma entidade ou um objeto de valor. Se dois objetos têm propriedades idênticas, mas ainda assim precisamos fazer a distinção entre eles, então é mais provável que cada um seja uma entidade com uma identificação única.

No caso em que dois objetos tenham propriedades idênticas e nós não nos importaremos com qual é qual, então teremos dois objetos de valor. Se o mesmo objeto pode ser partilhado, por exemplo, o mesmo nome pode ser conectado a vários objetos individuais, provavelmente irá se tratar de um objeto de valor.

Agregados e raízes agregadas (Aggregate e Aggregate Root)

A representação de uma coleção de objetos que são ligados por uma entidade raiz (root aggregate). Os agregados (aggregates) são as principais unidades de trabalho presentes no DDD. Eles encapsulam suas implementações, a fim de garantir a consistência das mudanças ocorridas.

Os objetos raramente são “independentes”, eles possuem outros objetos ligados a eles ou mesmo fazem parte de um objeto maior. Um objeto do tipo Pessoa pode ter um objeto de Endereço, que por sua vez pode ter outra Pessoa associada a ele, caso mais de uma pessoa esteja registrada lá.

Há claramente uma necessidade de organizarmos os objetos de domínio em grupos lógicos, que são os chamados agregados. Um agregado é um grupo de objetos associados que são tratados como sendo uma unidade com o propósito de alteração de dados. Cada agregado tem uma raiz e seus limites claramente definidos.

A raiz é o único membro de um agregado ao qual os objetos externos podem fazer referência.

Persistence Ignore

No domínio de um projeto, o seu principal objetivo é a criação de um modelo de domínio. Com isso, é preciso identificar quais são os objetos que iremos precisar para realizar as funcionalidades desejadas em nossas aplicações.

Precisamos identificar as relações entre os diferentes objetos e como eles interagem entre si, além disso, precisamos descobrir se o objetivo de negócio dos nossos clientes se torna alcançável através do nosso modelo de domínio.

Aqui não precisamos saber da existência de banco de dados, nem precisamos saber como e onde os dados do domínio irão persistir ou mesmo se estes dados precisam persistir enquanto fazemos o modelo do domínio.

Esta “ignorância” com relação ao meio de persistência fará com que nossos modelos de domínio estejam livres de qualquer acoplamento com a camada de persistência da aplicação. Isto acabará por separar as preocupações da persistência e do seu mecanismo de comunicação do nosso modelo de domínio.

Com isso, a nossa aplicação estará livre de acoplamentos com qualquer forma de armazenamento de dados e daí será muito mais fácil de testá-la. Mas de qualquer forma, em uma aplicação real precisamos ter um banco de dados.

A questão aqui é que não será o modelo de domínio que terá conhecimento sobre isso. A camada que será responsável por saber e gerenciar persistências da nossa aplicação será a camada de Repositórios.

Repositórios (Repository)

O repositório é responsável por gerenciar a persistência das entidades e dos agregados. Um repositório pode recuperar um agregado por id ou salvar seu estado. Ao contrário dos Data Access Object (DAO), o repositório não contém uma série de métodos de localização, ao invés disso, eles usam o padrão de design para assim obter os objetos, independentemente de critérios de pesquisa.

Note que aqui um repositório não trata em termos de "dados", ele trata em termos de raízes agregadas. Aqui podemos dizer ao repositório para adicionar uma raiz de agregado em nossa coleção, ou podemos requisitar a um determinado agregado raiz essa adição.

O que podemos perceber aqui é que as raízes de agregação podem compreender uma ou várias entidades e objetos de valor, o que difere de uma DAL (Data Access Language) tradicional que nos retorna um conjunto de linhas existentes em nossas tabelas da base de dados.

Domínio de Serviços (Services Domain)

Os serviços de domínio são diferentes dos serviços de infraestrutura, por estes incorporarem e operarem com base nos conceitos do domínio e fazerem parte da linguagem ubíqua.

O conceito do evento existe na camada de domínio e a camada de domínio determina quando o evento deve ser levantado. Um e-mail de serviços de infraestrutura pode lidar com um evento de domínio por meio ...

Quer ler esse conteúdo completo? Tenha acesso completo