Vale a pena hoje começar um projeto pessoal para estudar já com arquitetura DDD(Domain driven design)?

Estou querendo fugir da arquitetura conhecida como bolovo (BLL, DTO, DAL…), porém estou achando que estarei usando um canhão para matar uma formiga.

2 curtidas

DDD está mais para bomba atômica do que canhão.

Não precisa se prender a siglas ou grandes doutrinas, se oriente por funcionalidades, de forma organizada, separada, sem fazer misturas. De resto são recursos necessários para o resultado acontecer. Pode até pegar algo proveitoso de uma sigla ou outra, mas não se rotule totalmente.

1 curtida

Bem, se seu objeto é estudar, deve focar no assunto que está estudando. O que exatamente você quer aprender?

Por que considera DDD um canhao? O que ele tem de excesso em relação a essa arquitetura BOLOVO? Aliás, por que você quer fugir dela?

Bom, vou tentar não escrever muito. Eu acho que DDD vale a pena ser aplicado mesmo para um projeto pequeno. Mas é preciso entender que DDD não é exatamente um estilo de arquitetura, é uma filosofia de desenvolvimento. E essa filosofia consiste em trazer o problema a ser resolvido - o domínio - para o centro das atividades de desenvolvimento de software. Sendo assim, ao aplicar DDD você tem 2 objetivos principais:

  • estabelecer uma linguagem ubíqua: desenvolvedores, usuários e especialistas do domínio precisam falar o mesmo idioma
  • a implementação deve ser escrita na linguagem ubíqua, o ou mais próximo possível dela

Para atingir esses objetivos é que foram propostos alguns padrões para que você consiga expressar o seu domínio: entidades, serviços, objetos de valor, contextos delimitados, etc.

Observe então, que a complicação do DDD não é na sua essência em si, mas tentar aplicar todos os padrões envolvidos numa pancada só. Já passei pelo mesmo dilema que você está passando, o que posso dizer é que uma implementação de sucesso do DDD exige também uma boa dose de pragmatismo. Vou dar um exemplo: em uma implementação “pura” de DDD a validação dos campos de uma classe deveria ficar logo nos setters da entidade, para garantir a consistência da entidade de maneira encapsulada. Por outro lado, no ambiente JEE você pode usar BeanValidation para resolver essa tarefa e economizar muito tempo e esforço de desenvolvimento. Obviamente, a minha escolha foi usar o framework e concentrar o esforço de modelagem e desenvolvimento em regras mais significativas, entendeu ?

Para mim, um bom método para aplicar DDD seria o seguinte: faça um rascunho de como seria uma “implementação perfeita” de DDD: você teria uma camada de domínio pura, sem dependência com frameworks ou bibliotecas externas, camadas muito bem separadas,etc. A partir dessa arquitetura inicial aplique um enxugamento pragmático: retire o que for excessivo, quebre alguns “dogmas” para ganhar produtividade, mas sem perder a essência do DDD.

3 curtidas

Concordo com o rmendes! E tb não custa lembrar q o próprio Eric Evans diz (em seu livro) q provavelmete nenhum sistema em produção utilize todas as técnica, conceitos e pricípios do DDD.
Apesar de os building blocks ajudarem bastante na assimilação da abordagem, Domain-Driven Design é sobre “triturar o conhecimento” do domínio da Aplicação e por isso q deve haver uma ótima comunicação entre os desenvoldores e os experts do negócio. A ubiquitous laguage é essencial p/isso e NÃO deve ficar apenas na “fase” de requisitos: deve chegar ao código-fonte com a mesma clareza e fluencia; vide as Domain-Specific Laguages!

1 curtida

Caso estiver usando ASP.NET MVC como colocou nas tags, relaxa que a própria ferramenta já te orienta a seguir o padrão de arquitetura que ela segue. No projeto models é mais questão de se organizar para que o projeto possa crescer sem complicações. Isso existe desde sempre, até quando se lidava com papéis. Fica a critério de cada equipe, mas prefiro agrupar em pastas por assuntos de negócio, por exemplo “Clientes”, e lá dentro as funcionalidades e itens periféricos necessários para atender as mesmas, não obrigatoriamente tendo que ter uma sequencia de camadas.

Quando o cliente pede melhoria numa regra de negócio, você deve ter a facilidade de chegar lá e ficar focado no assunto solicitado. No bolovo e até em projetos seguindo pseudo “DDD”, vemos sacolas enormes de diversas Entidades, Services, Repositorios, etc. Dai você quer dar manutenção na parte de Cliente e tem que ficar catando onde tem algo relacionado a cliente em cada uma dessas sacolas cheias de coisas.

1 curtida

Mendes, valeu mesmo pela resposta, provavelmente vou escolher a sua resposta como solução, não estou em casa agora. Depois respondo melhor!

Para você, qual seria a maneira mais enxuta de trabalhar sozinho com o conceito de DDD? Visto que para trabalhar sozinho, isso resultaria em um ganho de produtividade? Pode me dar um exemplo desde a tratamento de uma requisição no client até a persistência dessa informação na camada Repository… Passando pelas camadas?

Na minha opinião, uma maneira de enxugar a estrutura é “engordar” um pouco o seu controller/presenter. Por exemplo, no controller rest, além de tratar conversões para json, códigos HTTP e etc. você também marcaria os seus métodos como transacionais, sem necessidade de um facade ou EJB adicional para isso. Assim, este mesmo controller trataria de invocar repositórios, entidades e serviços do domínio. Enfim, acho que para chamar de DDD só não se pode abrir mão de separar aplicação de domínio.

Controller seria só o meio de campo para transferência de dados, transação é regra de negócio, que deve estar centralizada no Model, ou Domain para quem segue DDD. Nem eu que não sigo DDD deixo isso fora do Model. Seria forçar a barra chamar de DDD, parece estar usando de forma avulsa padrões Repository, Service, etc. Por outro lado, concordo que é melhor (menos burocrático) do que seguir DDD.

Mendes, confesso que também acho que causa uma certa bagunça fazer transação na no controller. Sempre tento seguir que o controller é somente o cara que delega tudo.

Como você monta a sua estrutura?
Usa DTO (Data Transfer Object)?
Como consegue não seguir o DDD e não tratar regras de negócio no controller?

O que mais vejo é gente fazendo … é criar uma instância do repositório no controller e usa-lo diretamente no controller, junto com lógica de negócio e persistência de dados. Isso causa acomplamento? A persistência dos dados não deveria ser feita dentro do Repositório?

Acredito que a intenção do Mendes tenha sido passar uma forma simplificada de uso de alguns padrões sugeridos pelo DDD. São padrões independentes de seguir ou não DDD. Só não colocaria o que foi descrito como “chamar de DDD”. Entre outras coisas, DDD defende reutilização do domínio, onde no caso descrito não fica íntegro. Por outro lado isso não deve importar pra ele, se ele só precisa reutilizar as APIs REST como um todo.

Sobre estrutura, depende da necessidade de cada caso. Pra ficar mais prático, o ideal seria citar diretamente um exemplo de requisito de Negócio do seu sistema. Em relação a parte técnica, se o framework que você utiliza segue a arquitetura MVC, então está sob uma arquitetura que já deixa claro que toda regra de negócio e acesso a dados devem ficar no Model. Para organizar o Model, fica ao critério da equipe, importante é todo mundo se entender e a manutenção ser confortável.

Partindo do que você tem hoje (“bolovo”), uma sugestão genérica para melhoria:

O principal ponto ai é organizar por algo relacionado ao processo, “Cadastro de Pacientes” por exemplo, e não ter sacolas de todos os Services, Entidades, Repositorios, etc. Isso me facilita em ter melhor foco. Recursos técnicos você adiciona conforme a necessidade. Pode partir por exemplo de uma classe de Serviço, que vai ser responsável pela transação e coordenação de todo processamento da funcionalidade. Conforme precisar durante o processamento, você faz chamadas a mecanismos para validação, acesso a banco de dados, etc. Pode adotar o padrão que quiser, importante é saber quem estabelece as operações para o Negócio.

Outro ponto importante, evitar ter “sistemão” que atende todas as áreas da empresa. Tem que ser um para cada finalidade. Em uma clínica por exemplo, você poderia ter um sistema para administração, agendamento, recepcionamento, atendimento na sala do médico, etc, onde os models podem ser compartilhados conforme a necessidade.

Evite também usar o que for atrapalhar mais do que ajudar, mesmo que o Papa da TI diga que é super importante. Eu por exemplo, por questões de preferencia, não uso modelagem orientada a objetos, trabalho orientado a dados, com entidades refletidas diretamente do modelo de entidades-relacionamento do banco, e funcionalidades de acordo com os processos do Negócio. Outra coisa que não uso, Interface sem necessidade real, já vi muitos casos de contratos para uma eterna única implementação.

Se algo dito aqui atrapalhar mais do que ajudar, também não use, ou adapte a sua realidade.

O mais importante é particionar bem as coisas, se deixar ficar complexo, ai sim DDD pode entrar em ação.

Eu acho que o ponto que vocês deixaram passar é esse aqui:

Assim, este mesmo controller trataria de invocar repositórios, entidades e serviços do domínio

No contexto do DDD um serviço do domínio não representa uma transação, necessariamente. Serviços do domínio são justamente regras de negócio que não “cabem” em uma única entidade ou agregado. Por fazerem parte do domínio, estes objetos não devem conhecer detalhes da infra-estrutura: transações, banco de dados, sistema de arquivos, rede, e-mail, filas de mensagens, etc. E na minha opinião, é neste ponto que existe a confusão maior. Ao se confundir serviços do domínio com os serviços da aplicação as responsabilidades acabam misturadas e então, o que vemos mais frequentemente é expressar as regras de negócio como interações entre a infra-estrutura (transaction scripts), e é justamente isso que queremos evitar com o DDD. Assim, a minha sugestão de engordar o controller com controle de transações foi justamente para preservar os serviços do domínio.

Se você já esta familiarizado com arquitetura bolovo já era, agora só resolvendo problemas diferentes daqueles que arquitetos bolovos costumam resolver pra conseguir desprogramar sua mente de toda essa papagaiada de camadas, e que tudo tem que ser “desacoplado”.

Você pode tentar programação embarcada, desenvolvimento front-end, ou aprender uma linguagem funcional, se quer algo realmente diferente no back-end em termos de produtividade.

tem algum exemplo desses problemas ?

Garantir a transação faz parte do negócio, claro que a infraestrutura de como isso acontece não fica ali.

Sobre n tipos de serviços, sei que misturar é pecado nas conformidades do DDD ou padrões sugeridos, mas em nenhum momento quero seguir algo a risca, e bem longe de querer seguir DDD. Pra mim, atrapalha mais do que ajuda, fica burocrático quando o negócio é bem dividido. No exemplo apenas segui de ter a “camada” Model, se ele já tiver usando ferramenta que siga MVC (como neste exemplo http://blog.algaworks.com/spring-mvc/). Ali no Model (que é responsável pelas regras de negócio, validações e acesso ao banco), ele ou a equipe organiza como decidirem ser mais confortável para manutenção, partindo das necessidades de um processo específico. É nesse ponto que ele vai garantir toda a transação do negócio que estiver atendendo.

O mais importante seria ele passar as necessidades, essa coisa de tecnologia sem saber das necessidades de fato acaba criando “camadas” e abstrações a toa.

Dei alguns exemplos mas tanto faz, o importante é fazer um detox da filosofia Java de querer complicar as coisas mais simples.