# DDD Quickly - Parte 1 - 18/06
## Gab
### cap 1
- combina design e desenvolvimento para criar soluções melhores
- feedbacks ajudam no processo de criar models mais claras
- para criar uma model, é preciso ter informações essenciais e generalizadas do domain
### cap 2
- Ubiquitous Language
- mudanças no código ou na obiquitous language devem refletir na model
- para registrar a model podemos usar uml, documentação e outras ferramentas que se complementam
### cap 3
- analysis model
- layers
### Entity
- a entidade deve ser um atributo, uma combinação de atributos ou um atributo específico (ID)
### Value Objects
- não importa qual objeto, mas sim seus atributos
- immutable
- compartilhados
- mais faceis de criar e destruir
- não consomem tanata memoria
### Service
- não tem estado
- seu objetivo é adicionar funcionalidades/conceitos ao domain que não pertencem a Entity ou Value object
### Modules
- organizar conceitos relacionados para diminuir a complexidade
>code should have a high level of
cohesion and a low level of coupling
#### Communicational cohesion
- quando as funções do module operam sobre o mesmo dado
-
#### The functional cohesion
- quando funções do module trabalham juntos para performar uma task definida
### aggregates
- root é uma entidade com referencias a qualquer objeto "aggregate". O root é o único que da para ser acessado do lado de fora
- não da pra mudar os objetos diretamente, apenas a partir do root
- o root pode passar Value objects para objetos externos.
### factory
- criar uma interface para encapsular o processo de criarção de objetos complexos.
- são úteis para a criação de aggregates. Quando o root é criado, todos seus objetos também são
### factory method
- é um método que encapsula a lógica para criar outros objetos
- adicionar um método ao aggregate root que ficará responsável pela criação do objeto
## Johny
- Quando começamos um projeto de software, devemos nos concentrar no domínio em que estamos operando. O objetivo de todo software é a melhora de um domínio específico. Para podermos fazer isso, o software deve se encaixar harmoniosamente com o domínio para o qual foi criado, caso contrário, ele introduzirá tensão no domínio, provocando mal funcionamento, danos e até caos. O software deve ser um reflexo, incorporando os principais conceitos e elementos do domínio e percebendo com precisão os relacionamentos entre eles. O software deve modelar o domínio. Software que não tem raízes profundamente enraizadas no domínio não reagirá bem à mudança ao longo do tempo;
- troca de conhecimentos entre o designer (arquitetos, desenvolvedores, etc, de software) e o especialista sobre o domínio. O designer faz perguntas e as respostas vão trazendo os conceitos essenciais, de forma desorganizada, que então são esboçados. No desenvolvimento de um protótipo, o feedback de ambos os lados é essencial para chegar na versão polida. É um processo demorado, mas essencial;
- designer e especialista falam línguas diferentes, é necessário encontrar uma linguagem em comum durante o desenvolvimento. Um princípio básico do DDD é usar uma linguagem baseada no modelo (a Linguagem Ubíqua). Ela deve ser usada durante a comunicação e em código; na fala, escrita e nos diagramas (código bem escrito pode ser usado na comunicação). Mudanças na linguagem refletem em mudanças no modelo. Na criação de tal linguagem, é essencial manter foco no essencial;
- projete uma parte do sistema de software para refletir o modelo do domínio de maneira literal, para que o mapeamento seja óbvio. Revise o modelo e modifique-o para ser implementado de forma mais natural no software, refletindo uma visão mais profunda do domínio. Exija um modelo único que atenda bem a ambos os propósitos, além de oferecer suporte a uma Linguagem Ubíqua;
- quando criamos uma app, grande parte dela não está diretamente relacionada ao domínio, mas faz parte da infraestrutura ou atende ao próprio software;
- particione um programa complexo em CAMADAS. Desenvolva um design dentro de cada CAMADA que seja coeso e que dependa apenas das camadas abaixo. Siga os padrões arquiteturais para fornecer um acoplamento flexível às camadas acima. Concentre todo o código relacionado ao modelo do domínio em uma camada e isole-o da interface do usuário, da app e do código da infraestrutura. Os objetos do domínio, livres de responsabilidades, podem se concentrar em expressar o modelo do domínio. Isso permite que um modelo evolua para ser rico e claro o suficiente para representar as regras de negócio e colocá-las em funcionamento;
- arquitetura comum de DDD:
- Interface do usuário (camada de apresentação): responsável por apresentar informações ao usuário e interpretar os comandos do usuário;
- Camada de aplicação: é uma camada fina que coordena a atividade da aplicação. Não contém lógica de negócio nem mantém o estado dos objetos de negócio, mas pode conter o estado de progresso da tarefa da app;
- Camada de domínio: coração do software comercial. O estado dos objetos de negócio é mantido aqui. A persistência dos objetos e possivelmente seu estado é delegado à camada de infraestrutura;
- Camada de infraestrutura: atua como uma biblioteca de suporte para todas as outras camadas. Fornece comunicação entre camadas, implementa persistência para objetos de negócio, contém bibliotecas de suporte, etc.
- Parar para refatorar código de tempos em tempos. Temos feito muitos comentários recentes em MR referentes a futuras refatorações, manter um histórico destas discussões e trazer para lidar com débito técnico quando for pertinente? "That means time and resources, something we seem to never have enough"
- É muito fácil começar com um bom modelo e acabar com um inconsistente. O primeiro requisito de um modelo é ser consistente, com termos invariáveis e sem contradições.
- Quando vários times trabalham com um mesmo modelo pode ocorrer de um time o iniciar e outros o modificarem para atender as suas necessidades, futuramente quebrando as aplicações.
- Evitar um grande modelo, construir vários menores e com relações precisas. Um modelo deve ser pequeno o suficiente para que apenas um time lide com ele. "We need to communicate inside the team to make sure we all understand the role played by each element in the model. If one does not understand the relationships between objects, they may modify the code in such a way that comes in contradiction with the original intent."
- Customer role e supplier role ao dividir banco de dados entre dois times. É necessário comprometimento.
- Camada anticorrupção: entre o modelo do cliente e o externo. Usa linguagem diferente para os diferentes modelos, não contaminando um ao outro. Pode conter mais de um Service.
- Separate Ways: várias aplicações menores que têm pouco ou nada em comum da perspectiva da modelagem. Modelados separadamente, podem usar da tecnologia que for preferencial. Possui contextos interligados.
- Open Host Service: tradutor entre o sistema cliente e o sistema externo a ser integrado. O sistema externo deve providenciar Services por protocolo para todos os outros sistemas, de forma a possuir uma única tradução.
- Distillation: quando o modelo ainda é grande, mesmo após refatorações, entra em cena o processo de destilação. A ideia é definir um Core Domain que representa a essência do domínio, separando conceitos essenciais de conceitos genéricos. Importante que seja muito bem desenvolvido. Requer muito refinamento e refatoramento, e outros elementos do modelo devem ser repensados em volta do Core Domain.
- Subdomains Genéricos: criados a partir do processo de destilação. formas de implementá-lo:
- Solução pronta para uso: já foi feita por alguém, talvez seja preciso lidar com alguns bugs;
- Terceirização: implementado por outro time, provavelmente de outra empresa. Deve ser integrado apenas;
- Modelo existente: implementar um modelo já existente;
- Implementação interna: possui alto nível de integração, mas requer tempo e recursos.
- Keep in mind some of the pitfalls of domain modeling:
1) Stay hands-on. Modelers need to code.
2) Focus on concrete scenarios. Abstract thinking has to be anchored in concrete cases.
3) Don't try to apply DDD to everything. Draw a context map and decide on where you will make a push for DDD and where you will not. And then don't worry about it outside those boundaries.
4) Experiment a lot and expect to make lots of mistakes. Modeling is a creative process.
## Igor
- Linguagem ubíqua
- Analysis model: result of business domain analysis, resulting in a model which has no consideration for the software used for implementation
- Very important details are discovered during the design and implementation process.
- A better approach is to closely relate domain modeling and design
- Esse livro vale pra toda a equipe/stakeholders, não só os devs.
- Anyone responsible for changing code must learn to express a model through the code.
**The Building Blocks Of A Model-Driven Design**
_Object modeling and software design from the viewpoint of domain-driven design._
**Arquitetura de Camadas**
- Arquitetura de camadas para isolar os dominios.
- Modelos com o foco de serem expressivos e claros.
- As 4 camadas: interface com usuario(apresentação), aplicação (sem regras de negocio), dominio (info sobre o dominio), infra (camada de apoio, persistencia, comunicação com outras camadas)
- Estabelecer regras de interação entre essas camadas é importante.
**Entidades**
- Implementar entidades significa criar identidade.
- Reconhecer entidades no inicio da modelagem é importante.
**Value objects**
_Um objeto que é usado para descrever certos aspectos de um domínio, e que não tem identidade é chamado Value Object_
- We are not interested in which object it is, but what attributes it has.
- É altamente recomendável que _Value Objects_ sejam imutáveis;
- Sendo imutáveis e não tendo identidade, _Value Objects_ podem ser compartilhados;
- Exemplo da aplicação de desenhos
**Serviços**
_"Services act as interfaces which provide operations."_
1. operações performadas pelo serviço se referem a um conceito do dominio, que não pertence naturalmente a uma entidade ou value object
2. a operação se refere a outros objetos no dominio
3. a operação é stateless
- When a significant process or transformation in the domain is not a natural responsibility of an Entity or Value Object, add an operation to the model as a standalone interface declared as a Service.
**Módulos**
_"Escolha Módulos que contem a história do sistema e contenham um conjunto coeso de conceitos."_
- Coesão comunicacional e funcional
**Aggregates**
- Define ownership e limites (_boundaries_);
- Factories and Repositories are two design patterns which help us deal with object creation and storage;
- An Aggregate contains a series of objects that are closely related;
- The construction of the root is related to the creation of the other objects in the Aggregate.;
**Factories**
"_Encapsula o processo de criação de um objeto complexo, especialmente útil na criação de _Aggregates_."_
ex.: calculo de rota de um carro da origem ao destino baseado em restrições:
-- Use a constructor when:
- The construction is not complicated.
- The creation of an object does not involve the creation of others, and all the attributes needed are passed via the constructor.
- The client is interested in the implementation, perhaps wants to choose the Strategy used.
- The class is the type. There is no hierarchy involved, so no need to choose between a list of concrete implementations.
**Repositórios**
- Evita exposição de detalhes internos do banco/infraestrutura;
- Em vez de lidar com detalhes de infra lida com os conceitos do dominio;
- Strategy
- Encapsula toda a logica necessaria para obter as referencias dos objetos;
- Mais clareza e foco
- O repositorio pode armazenar referencias de alguns objetos
- Meio-campo entre camada de modelo do dominio e db/factories/outros repos etc (mapeamento de dados).
- Keep the client focused on the model, delegating all object storage and access to the Repositories.

### Refactoring Toward Deeper Insight**
**Continuous Refactoring**
_Lendo o código deve ser possível entender o que ele faz e também o porquê._
**Bring Key Concepts Into Light**
_Tornar conceitos implicitos em explicitos_
- Se um conceito chave estiver faltando outros terão que repor sua funcionalidade. Isso vai tornar alguns objetos maiores adicionando comportamentos que não deveriam estar lá. Ruim pra clareza do design.
- Procure um conceito faltante. Se encontrado torne-o explicito. Refatore.
### Bruno
## Juliana
### Capítulo 1
### O que é design orientado a domínio?
- **DDD** é importante para o desenvolvimento de *softwares mais complexos*, visto que é necessário ter um vasto conhecimento do domínio de negócio para que o software tenha valor e seja de fato útil. Ele utiliza o exemplo de um software bancário, dizendo que é impossível construir um software para bancos sem saber como um banco funciona
- Um domínio é algo do **mundo real**, e é necessário criar abstrações para que isso seja refletido em código
- Uma abstração de domínio é basicamente um *modelo*
- Um domínio contém informação demais para um único *modelo*, e é um desafio por si só criar uma representação abstrata de todo domínio distribuído em partes (diversos *modelos*)
- Outro desafio é a comunicação entre o *modelo*, os experts de domínio, os desenvolvedores e os designers. Uma forma de fazer isso é utilizar diagramas, casos de uso, etc; e outro modo é escrevendo sobre o domínio
- Ao associar uma metodologia de *desenvolvimento cascata* ao **DDD** podemos sofrer over-engineering, visto que teriamos de ter todos os requisitos de domínio descritos previamente e não podemos efetuar mudanças. Em contra partida ao utilizar alguma *metodologia ágil* como XP, por ter como princípio a simplicidade é fácil produzir código de difícil leitura e manutenção, visto que pode-se efetuar refatorações ao longo do processo
- **DDD** combina design e práticas de desenvolvimento, o que pode criar soluções de software melhores
### Construíndo conhecimento de domínio
- O autor usa como exemplo um *sistema de controle de voo*, não um sistema complexo de monitoramento de todo fluxo aéreo, mas somente um subsistema de monitoramento de um voo
- Devemos começar pelo entendimento do domínio, onde diversos especialistas descrevem seus pontos de vista, e a partir dessa descrição somos capazes de criar modelos que melhor representem a realidade. O modelo tirado do exemplo foi:
**n**
**|aircraft| ---> |route| ---> |fix| ---> |2D point|**
- Compreender as partes essenciais do domínio é muito importante para o design. E isso acontece através de longas discussões entre especialistas do domínio e os arquitetos / desenvolvedores de software. **Todas as partes devem ser envolvidas no momento de criar os modelos**
### Capítulo 2
## Linguagem umbíqua
- É importante que no momento de contruir um modelo tanto os especialistas no domínio, quanto os desenvolvedores, sejam capazes de realizar uma *boa comunicação* e entender o que um e o outro estão dizendo
- O projeto pode sofrer sérios problemas se não houver uma linguagem comum entre as partes
- Durante as conversas é comum utilizar **traduções**, os desenvolvedores utilizam linguajar técnico enquanto os especialistas de domínio utilizam jargões. É importante que ambos se esforcem para explicar seus pontos com linguagem mais comum a todos
- Qual linguagem é a mais adequada para que todos se comuniquem? a dos programadores? dos especialistas? do domínio?, ou algo no meio do caminho?
- O princípio central do **DDD** é utilizar a linguagem baseada no **MODELO**, que deve ser o ponto em comum entre todos
- Pode *demorar* bastante tempo até que todos se ajustem a nova linguagem, é algo que exige esforço de todos
- Especialistas de domínio devem compreender perfeitamente os modelos apresentados, caso isso não ocorra é sinal de que *talvez algo esteja errado*. Em contra partida os desenvolvedores devem se atentar para **ambiguidades e inconsistências** que podem aparecer nos modelos
## Criando a linguagem umbíqua
- O autor nos mostra um diálogo entre o desenvolvedor e o especialista, que se passa durante a criação do modelo, que representa o domínio de monitoramento de voos
- Decide-se então incluir ao modelo anterior o item: **flight plan**
**|aircraft| ---> |flight plan| ---> |route| ---> |fix| ---> |2D point|**
- Ao criar classes para os conceitos do modelo estamos criando um mapa entre o modelo e o código, e a linguagem e o código. Isso permite que o código seja mais legível
- Utilizar diagramas **UML** é uma ótima forma de representar as classes e seus relacionamentos
- Deve-se ter cuidado com diagramas **UML**, para representar uma quantidade muito grande de classes
- Diagramas **UML** não são bons para representar comportamentos
- Evitar utilizar documentos antigos, com a linguagem errada e que não representam o modelo
- Outra forma de comunicação é através de código. É uma prática conhecida na comunidade **XP**
- Utilizar código *é uma boa forma* para representar comportamento
- Utilizar código *não é uma boa forma* para representar os modelos