6. Big Ball Of Mud – Grande Bola de Lama
• A arquitetura não é bem definida
• Correções e pequenas evoluções
tornam-se um grande desafio devido a
dificuldade de entender o código
• Evans: “BBoM é aquele código faz
alguma coisa útil, mas sem explicar
como”
7. “DDD é sobre a redução de complexidade
no software”
Eric Evans
8. DDD é um conjunto de princípios e práticas
aplicados na solução de problemas complexos...
Princípios e práticas baseados nas experiências
de Evans como consultor...
Eric Evans
11. Domínio do Negócio (Domain)
• Uma esfera de conhecimento
• O que ela faz e como ela faz...
• Cada empresa
• tem o know-how do segmento/problema que ela atende
• E o seu jeito de fazer
• Conhecer o domínio é a parte mais importante do DDD
12. DDD é sobre criar modelos altamente
expressivos
13. O que é um Modelo?
• Simplificação da realidade
• Mostra alguns aspectos da realidade
ou uma ideia de interesse
18. Modelo é uma representação mental
Todo o resto são apenas
ferramentas de
comunicação
19. Como construir um modelo no DDD ?
Domain Expert Dev. Team
• Conhece do negócio,
• Dos processos
• Das terminologias...
• Técnicos
• Interagem com o Domain
Expert para entender do
negócio
20. Logo...
• Domain expert acessível;
• Alta interação entre o domain expert e o time de desenvolvimento;
Manifesto Ágil
• Indivíduos e interações mais que processos e ferramentas
• Colaboração com o cliente mais que negociação de contratos
• Princípio: Pessoas relacionadas à negócios e desenvolvedores devem
trabalhar em conjunto e diariamente, durante todo o curso do
projeto.
http://www.manifestoagil.com.br
30. Problema
Domínio
VendoLivros S/A
Loja de Livros A VendoLivros S/A é uma empresa
que comercializa apenas livros, seu
grande diferencial está na entrega,
que é bem mais rápida que seus
concorrentes devido a sua grande
expertise em logística e
distribuição.
32. Lei de Conway
Presidência
Vendas
..
Marketing
..
Pagamentos Estoque Entrega ...
Resumo: A forma como as organizações estão estruturadas
tem um forte impacto sobre os sistemas que elas criam
"Qualquer empresa que projeta um sistema (definição mais ampla
aqui do que apenas sistemas de informação), inevitavelmente produz
um projeto cuja estrutura é uma cópia da estrutura de comunicação
da organização.“ Melvin Conway (1968)
34. Decompondo o problema Subdomínio
Estoque
RH, Financeiro
Tesouraria
...
Vendas
Marketing
Entrega
Domínio
VendoLivros
Catálogo
Pedidos
Preços
Localização
Armazenamento
Taxa de entrega
Prazo de entrega
Parceiros de transporte
Propaganda
Promoções
Pagamentos
Boleto
Cartão de Crédito
Presidên
cia
ndas
..
Marketi
ng
..
Pagame
ntos
Estoque Entrega ...
35. Decompondo o problema Subdomínio
Estoque
RH, Financeiro
Tesouraria
...
Vendas
Marketing
Entrega
Pagamentos
Domínio Principal (Core Domain)
• Sucesso para o negócio
• Focar todos os esforços
36. Decompondo o problema Subdomínio
Estoque
RH, Financeiro
Tesouraria
...
Vendas
Marketing
Entrega
Pagamentos
Domínio Principal (Core Domain)
• Sucesso para o negócio
• Focar todos os esforços
Subdomínio de Suporte
• Essenciais mas não o core
• Desenvolver ou comprar
37. Decompondo o problema Subdomínio
Estoque
RH, Financeiro
Tesouraria
...
Vendas
Marketing
Entrega
Pagamentos
Domínio Principal (Core Domain)
• Sucesso para o negócio
• Focar todos os esforços
Subdomínio de Suporte
• Essenciais mas não o core
• Desenvolver ou comprar
Subdomínio Genérico
• Não agrega valor para o negócio
• Se possível, Comprar / Github
39. Foco no Domínio Principal
Não perca tempo e esforço para refatorar todo o seu código, foque no
domínio principal!
Para subdomínios de suporte e genéricos, o código bom é o suficiente.
A perfeição é uma ilusão, e deve ser reservada apenas para o que é
essencial
O negócio não se preocupa com a qualidade do código
para as áreas que não são essenciais
Scott Millett
40. Decompondo o problema Modelo de Domínio (Domain Model)
Estoque
RH, Financeiro
Tesouraria
...
Vendas
Marketing
Entrega
Pagamentos
Representa a lógica de domínio e as
regras de negócios que são relevantes
para o subdomínio
Modelo de
Domínio
Modelo de
Domínio
Modelo de
Domínio
Modelo de
Domínio
Modelo de
Domínio
Modelo de
Domínio
Livro
43. Contextos Delimitados (Bounded Context)
• Definem a maneira como um subdomínio será resolvido
tecnicamente pela solução
• Enquanto o conceito do Subdomínio pertence ao que chamamos de
Espaço Problema, os Contextos Delimitados pertencem ao Espaço
Solução
45. Contextos Delimitados (Bounded Context)
Contexto de
Catálogo
Contexto de
Precificação
Contexto de
Pedidos
Subdomínio de Vendas
Contexto de
Promoções
Contexto de
Publicidade
Subdomínio de
Marketing Contexto de
Estoque
Subdomínio de
Estoque
Contexto de
Pagamento
Subdomínio de
Pagamento
Contexto de
Entrega
Subdomínio de
Entrega
Contexto de
ERP Legado
Subdomínio de
ERP Legado
46. Contextos Delimitados (Bounded Context)
Contexto de
Catálogo
Contexto de
Precificação
Contexto de
Pedidos
Subdomínio de Vendas
Contexto de
Promoções
Contexto de
Publicidade
Subdomínio de
Marketing Contexto de
Estoque
Subdomínio de
Estoque
Contexto de
Pagamento
Subdomínio de
Pagamento
Contexto de
Entrega
Subdomínio de
Entrega
Contexto de
ERP Legado
Subdomínio de
ERP Legado
Sistema VendoLivros Online
48. Contextos Delimitados (Bounded Context)
Contexto de
Catálogo
Contexto de
Precificação
Contexto de
Pedidos
Subdomínio de Vendas
Contexto de
Promoções
Contexto de
Publicidade
Subdomínio de
Marketing Contexto de
Estoque
Subdomínio de
Estoque
Contexto de
Pagamento
Subdomínio de
Pagamento
Contexto de
Entrega
Subdomínio de
Entrega
Contexto de
ERP Legado
Subdomínio de
ERP Legado
• Tornar o Implícito Explicito
• Define explicitamente o
contexto dentro do qual
um modelo se aplica.
• É delimitado pela
linguagem compartilhada
• Protege seu modelo
Livro
Livro
Livro
Livro
Livro
Livro
Livro
53. Mapa de Contexto
• Estabelece uma visão da comunicação entre as equipes
• Torna as delimitações dos contextos explícitos
• Fornece a visão para possíveis alterações e evoluções
• Estabelece um conjunto de padrões de comunicações
• Núcleo compartilhado
• Cliente Fornecedor
• Conformista
• Parceria
• Camada de Anticorrupção
• Linguagem Publicada
55. Núcleo Compartilhado (Shared Kernel)
• Dois times compartilham um subconjunto de modelo de um mesmo subdomínio
• Alterações dentro do núcleo compartilhado devem ser acordadas entre as duas
equipes
• Integração Contínua
• Geralmente é o Domínio Principal
Contexto de
Folha de Pagamento
Contexto de
Recursos Humanos
Modelo de Domínio
Do Funcionário
Subdomínio
Recurso Humanos
56. Baseado em direções
• O Downstream é o lado do relacionamento que depende de dados ou
comportamentos do lado Upstream
Contexto
Downstream
Contexto
Upstream
57. Cliente/Fornecedor (Customer/Supplier)
• É uma relação de cliente e fornecedor
• Orçar/Estimar
• Planejamento da entrega
• Direito a veto, negociar com o Fornecedor
• Interação – O team Cliente deve estar disponível para sanar dúvidas
Contexto Vendas Contexto
Pedidos
Customer-Supplier
Downstream Upstream
Consome/utiliza de
58. Cliente/Fornecedor (Customer/Supplier)
• Testes automatizados
• Escritos pela equipe de cliente (definindo a interface esperada)
• Executados pela equipe Fornecedor (Para garantir que não estão quebrando
nada)
Contexto Vendas Contexto
Pedidos
Customer-Supplier
Downstream Upstream
Consome/utiliza de
59. Cliente/Fornecedor (Customer/Supplier)
• Equipes de Clientes/Fornecedores tem maior chance de sucesso se
elas trabalham sob a mesma gerência e compartilham os mesmos
objetivos
Contexto Vendas Contexto
Pedidos
Customer-Supplier
Downstream Upstream
Consome/utiliza de
60. Conformista (Conformist)
• Não há colaboração entre o contexto downstream e o upstream
• Muito comum em relacionamento com contextos que representam
um sistema de terceiro, API...
A A
Contexto Vendas Contexto
Pagamentos
Conformista
Downstream Upstream
Consome/utiliza de
61. Conformista (Conformist)
• Se o Upstream é uma bagunça, essa bagunça será propagada para o
Downstream
• É caro criar uma camada de tradução para que os objetos do
upstream não corrompem o modelo do downstream
A A
Contexto Vendas Contexto
Pagamentos
Conformista
Downstream Upstream
Consome/utiliza de
62. Camada de Anticorrupção (Anti-Corruption Layer)
• Criar uma camada para tradução entre os termos do Upstream para o
modelo do Downstream, e vice-e-versa.
• Protege o modelo de domínio de influências externas
Contexto Vendas Contexto
Pagamentos
ACL
Anti-Corruption
Layer
Downstream Upstream
64. Parceria (Partnership)
• Dependência mútua entre os contextos/equipes, elas obtém o sucesso ou
fracasso juntas;
• Possuem um objetivo em comum
• Cooperam na evolução das interfaces para acomodar as necessidades de ambos
• Entregas/Releases são alinhadas
Contexto Vendas Contexto Pedidos
Partnership
65. Caminhos separados (Separate Ways)
• Quando realmente não há relacionamento entre os contextos
• Quando o custo de tradução é tão grande que é preferível a duplicação de parte
do modelo e que eles sigam em Caminhos separados.
Contexto Publicidade Contexto Entrega
66. Linguagem Publicada (Published Language)
• Quando você quer abrir seu contexto para integração com vários clientes
• Se muitos contextos compartilham a mesma lógica de tradução, pode ser
preferível que se tenha uma forma de acesso com interfaces claramente
definidos
• Define o protocolo de comunicação
Serviço Aberto de Funcionalidades
(Open/Host Service)
• Quando você quer definir uma linguagem comum para comunicação
67. Comunicação através de API REST, JSON/XML
Contexto Pedido
Contexto Estoque
Contexto Entrega
Contexto Catálogo
OHS
68. A estratégia sem tática é o caminho mais lento para a vitória.
Sun Tzu
Arte da Guerra
75. public class Livro
{
public Guid Id {get; private set;}
public string Titulo {get; private set;}
public Autor Autor {get; private set; }
public decimal Preco {get; private set;}
public string ISBN {get; private set;}
public Livro(string titulo, Autor autor, string isbn)
{
if (string.IsNullOrEmpty(titulo))
throw new InvalidArgumentException("O Título do livro é obrigatório!");
if (autor == null)
throw new InvalidArgumentException("O Autor do livro é obrigatório!");
if (string.IsNullOrEmpty(isbn))
throw new InvalidArgumentException("O Código ISBN do livro é obrigatório!");
if ((isbn.Length != 10) && (isbn.Length != 13))
throw new InvalidArgumentException("O Código ISBN do livro é inválido!");
Titulo = titulo;
Autor = autor;
ISBN = isbn;
Preco = 0m;
}
public void AlterarPreco(decimal novoPreco)
{
if (novoPreco <= 0m)
throw new InvalidArgumentException("O novo preço informado deve ser maior do zero");
Entidade (Entity)
Tem uma identidade
Construtores
bem definidos
Invariantes
public Guid Id {get; private set;}
Livro Vem linguagem ubíqua
76. if (autor == null)
throw new InvalidArgumentException("O Autor do livro é obrigatório!");
if (string.IsNullOrEmpty(isbn))
throw new InvalidArgumentException("O Código ISBN do livro é obrigatório!");
if ((isbn.Length != 10) && (isbn.Length != 13))
throw new InvalidArgumentException("O Código ISBN do livro é inválido!");
Titulo = titulo;
Autor = autor;
ISBN = isbn;
Preco = 0m;
}
public void AlterarPreco(decimal novoPreco)
{
if (novoPreco <= 0m)
throw new InvalidArgumentException("O novo preço informado deve ser maior do zero");
if (novoPreco != novoPreco.Round(2))
throw new InvalidArgumentException("O novo preço deve ter apenas duas casas decimais");
Preco = novoPreco;
}
public override bool Equals(object obj)
{
return this.Id == ((Livro)obj).Id;
}
}
A igualdade é dada pelo seu ID (identidade)
Clareza
Invariantes
77. Objeto de Valor (Value Object)
public class ISBN
{
public string NumeroISBN {get; private set;}
public ISBN(string isbn)
{
if (string.IsNullOrEmpty(isbn))
throw new InvalidArgumentException("O Código ISBN do livro é obrigatório!");
if ((isbn.Length != 10) && (isbn.Length != 13))
throw new InvalidArgumentException("O Código ISBN do livro é inválido!");
if (!EhValido(isbn))
throw new InvalidArgumentException("O Código ISBN do livro é inválido!");
NumeroISBN = isbn;
}
public bool EhISBN10() => return NumeroISBN.Length == 10;
public bool EhISBN13() => return NumeroISBN.Length == 13;
public bool EhValido(string isbn) => { .... }
public override bool Equals(object obj)
{
return this.NumeroISBN == ((ISBN)obj).NumeroISBN;
}
}
Vem linguagem ubíquaISBN
* Construtores
bem definidos
* Invariantes
* Imutáveis
public string NumeroISBN {get; private set;}
public ISBN(string isbn)
{
if (string.IsNullOrEmpty(isbn))
throw new InvalidArgumentException("O Código ISBN do livro é obrigatório!");
if ((isbn.Length != 10) && (isbn.Length != 13))
throw new InvalidArgumentException("O Código ISBN do livro é inválido!");
if (!EhValido(isbn))
throw new InvalidArgumentException("O Código ISBN do livro é inválido!");
NumeroISBN = isbn;
}
Lógica
A sua igualdade é dada pelas
suas propriedades
78. • A sua igualdade é dada pelas suas propriedades
Objeto de Valor (Value Object)
79. public class Livro
{
public Guid Id {get; private set;}
public string Titulo {get; private set;}
public Autor Autor {get; private set; }
public decimal Preco {get; private set;}
public string ISBN {get; private set;}
public Livro(string titulo, Autor autor, string isbn)
{
if (string.IsNullOrEmpty(titulo))
throw new InvalidArgumentException("O Título do livro é obrigatório!");
if (autor == null)
throw new InvalidArgumentException("O Autor do livro é obrigatório!");
if (string.IsNullOrEmpty(isbn))
throw new InvalidArgumentException("O Código ISBN do livro é obrigatório!");
if ((isbn.Length != 10) && (isbn.Length != 13))
throw new InvalidArgumentException("O Código ISBN do livro é inválido!");
Titulo = titulo;
Autor = autor;
ISBN = isbn;
Preco = 0m;
}
public void AlterarPreco(decimal novoPreco)
{
if (novoPreco <= 0m)
throw new InvalidArgumentException("O novo preço informado deve ser maior do zero");
80. public class Livro
{
public Guid Id {get; private set;}
public string Titulo {get; private set;}
public Autor Autor {get; private set; }
public decimal Preco {get; private set;}
public ISBN ISBN {get; private set;}
public Livro(string titulo, Autor autor, ISBN isbn)
{
if (string.IsNullOrEmpty(titulo))
throw new InvalidArgumentException("O Título do livro é obrigatório!");
if (autor == null)
throw new InvalidArgumentException("O Autor do livro é obrigatório!");
if (string.IsNullOrEmpty(isbn))
throw new InvalidArgumentException("O Código ISBN do livro é obrigatório!");
if ((isbn.Length != 10) && (isbn.Length != 13))
throw new InvalidArgumentException("O Código ISBN do livro é inválido!");
Titulo = titulo;
Autor = autor;
ISBN = isbn;
Preco = 0m;
}
public void AlterarPreco(decimal novoPreco)
{
if (novoPreco <= 0m)
throw new InvalidArgumentException("O novo preço informado deve ser maior do zero");
public ISBN ISBN {get; private set;}
ISBN isbn
81. Objeto de Valor (Value Object)
• Reduz o code smell “Obsessão com tipos Primitivos”
• Outros exemplos:
• Dinheiro
• CEP
• CPF
• Chave NF-e
• ...
82. Agregado Raiz
Entidade
Objeto Valor
Agregados (Aggregate)
• Compostos de Entidades
ou Objetos de Valores
que são encapsulados
numa única classe;
• Serve para manter a
integridade do modelo;
• Possui uma raiz de
agregação (Aggregate Root);
• Único repositório por
raiz de agregação;
83. Agregados (Aggregate)
public class Livro
{
public Guid Id {get; private set;}
public Autor Autor {get; private set; }
public ISBN ISBN {get; private set;}
...
public IReadOnlyList<Exemplar> Exemplares { get { return _exemplares; } }
public void AdicionarExemplar(Exemplar exemplar)
{
if (_exemplares.Contains(exemplar))
throw new InvalidArgumentException("Exemplar já incluído.");
_exemplares.Add(exemplar);
}
public int ObterQuantidadeExemplares()
{
return _exemplares.Count();
}
}
84. Serviço de Domínio (Domain Service)
• Classes que contém uma lógica de negócio mas que não pertencem a
nenhuma entidade ou objeto de valor;
• Serviços não guardam estado (Stateless);
• Toda chamada a um mesmo serviço, com a mesma pré-condição deve retornar o mesmo
resultado.
• Orquestrar entidades e encapsular regras de negócios;
• Conceito de domínio que vem da LU e que envolve várias entidades;
• Protege o modelo (entidade / objeto de valor)
• Ex:
• CalculadoraFrete
• CancelamentoPedido
85. Evento de Domínio (Domain Event)
• Notifica aos interessados que algo importante aconteceu no domínio;
• Exemplo de eventos:
• Livro entregue
• Livro foi separado
• Livro foi enviado
• Pedido gerado
• OCP – Aberto para extensão e fechado para alteração
86. Critérios Técnicos
Por Conceitos da LU
Módulo (Module)
• Divide o código por conceito (LU) e não por
critério técnico;
• São usados para decompor o modelo de domínio;
• Permitem ao desenvolvedor ler e entender
rapidamente o modelo do domínio;
• Namespace / Projects
87. Fábrica (Factory)
• Utilize construtores apenas para criação de objetos simples,
• Para objetos complexos utilize fábricas
• Encapsula toda a lógica necessária para criar um Agregado em um
estado consistente
• Centraliza a lógica de criação
• Utilize os padrões GoF:
• Factory Method
• Abstract Factory
• Builder
88. Repositório (Repository)
• É o mecanismo que você deve usar para recuperar e persistir
agregados
• Persistência Agnóstica, é uma preocupação de infraestrutura, não do
modelo
• Pode ser útil se apoiar em estruturas de ORM (Entity Framework,
NHibernate)
• Um por Raiz de Agregação
• Não é indicado para Relatórios e telas de consultas complexas
Banco de
Dados
89. Especificação (Specification)
• Torna a regra de negócio implícita explicita
• Utilizado principalmente para validações
• Permite a criação de especificações compostas (utilizando E, OU, Não)
90. Quando NÃO utilizar DDD
Quando...
• o domínio não é complexo, pode ser resolvido com um simples CRUD
• a solução é muito mais técnica do que de negócio, Ex: Um framework
• o Domain Expert não é acessível
• você não tem um time motivado e qualificado
• o processo de desenvolvimento é cascata
91. Adotar DDD só porque é legal
Ignorar o DDD porque o domínio parece ser pouco complexo
92. E se você não seguir o DDD em aplicações
complexas...?
• Provavelmente você terá um modelo anêmico com muitos serviços
• Regras de negócios ficam espalhadas em classes que não são do
domínio
• Difícil de mudar o sistema em uma alteração/evolução da regra de
negócio
• Comunicação negligenciada
101. Conteúdo do Curso
• Introdução
• Linguagem Obíquoa
• Domínios Ricos vs Domínios
Anêmicos
• Sub Domínios
• Separação em Contextos
Delimitados
• Organizando a Solução
• Definindo as Entidades
• Corrupção no Código
• SOLID e Clean Code
• Primitive Obsession
• Value Objects
• Compartilhando Informações
entre Contextos Delimitados
• Testando as Entidades e VOs
• Commands
• Fail Fast Validations
• Testando os Commands
• Repository Pattern
• Handlers
• Testando os Handlers
• Queries
• Testando suas Queries
http://live.balta.io/