74
Domain Driven Design João Nicolau Oliveira http://netpont o.org 16ª Reunião Presencial - 11/12/2010

Domain-Driven Design

Embed Size (px)

DESCRIPTION

Domain-Driven Design não é uma tecnologia ou metodologia. DDD é uma abordagem à modelação de software que providencia uma estrutura de práticas, padrões de programação e terminologias que ajudam à sua concepção. Nesta sessão vamos conhecer o que é Domain-Driven Design, quando o usar e como implementar.

Citation preview

Page 1: Domain-Driven Design

Domain Driven DesignJoão Nicolau Oliveira

http://netponto.org16ª Reunião Presencial - 11/12/2010

Page 3: Domain-Driven Design

João Oliveira- Licenciado na Faculdade de Ciências de Lisboa- 12 anos de experiência em TI- Adepto das metodologias ágeis- Release Manager na Solutions Factory

C#ASP.Net

WPFWCFDNN

jQuery

DelphiJava

Zope

Page 4: Domain-Driven Design

Citação...

«Domain modeling is not a matter of making as “realistic” a model as possible. It is more like moviemaking, loosely representing reality to a particular purpose.»

Eric Evans

Page 5: Domain-Driven Design

Agenda

• O que é? Quando usar? Como?• Ubiquous Language, Bounded Contexts,

Integração Contínua, Context Map, Persistence Ignorance

• Command and Query Responsability Segregation• Patterns: Value Object, Entity, Aggregate, Factory,

Repository, Unit Of Work, Specification

Page 6: Domain-Driven Design

Também disponível em vídeo...

Assista!http://www.vimeo.com/21488644

Page 7: Domain-Driven Design

O que é DDD?– Focalização no domínio• Um domínio é um âmbito. • É definido por um conjunto de características que descrevem

uma família de problemas para os quais procuramos uma solução.• A análise do domínio identifica, captura e organiza

informação para que seja reutilizável aquando da criação de novos sistemas.

Page 8: Domain-Driven Design

O que é o modelo do domínio?

Page 9: Domain-Driven Design

O que é o modelo do domínio?

É uma representação

Page 10: Domain-Driven Design

O que é DDD?– Focalizar no modelo• Elaborar uma representação abstracta do domínio que nos

ajude a cumprir o propósito

– Linguagem omnipresente• Os peritos do domínio e os programadores partilham uma

linguagem comum

– É Object-Oriented e combina bem com outras metodologias ágeis• TDD, BDD, … Reduz complexidade/facilita manutenção.

Page 11: Domain-Driven Design

Quando usar?– Projectos em que os desenhadores do modelo estão

dispostos a “pôr as mãos na massa”– Colaboração efectiva entre peritos do domínio e os

developers– Abertura para explorar e experimentar (os primeiros

modelos não são satisfatórios)– Contexto explicito e bem definido– Apenas adequando para o núcleo do domínio

Page 12: Domain-Driven Design

Modelar - Como?

• Processo de melhoria, ajuste, adaptação, aprendizagem, experimentação

Modelos Emergentes

Linguagem Omnipresente

Page 13: Domain-Driven Design

Linguagem Omnipresente

Peritos de Domínio

Só nos entendemos se falarmos a mesma língua

Page 14: Domain-Driven Design

Linguagem Omnipresente

Peritos de Domínio Programadores

Só nos entendemos se falarmos a mesma língua

Page 15: Domain-Driven Design

Linguagem Omnipresente

Peritos de Domínio Programadores

Só nos entendemos se falarmos a mesma língua

Page 16: Domain-Driven Design

Linguagem Omnipresente

Peritos de Domínio Programadores

Só nos entendemos se falarmos a mesma língua

Page 17: Domain-Driven Design

Linguagem Omnipresente

Peritos de Domínio Programadores

Só nos entendemos se falarmos a mesma língua

“Alhos”

Page 18: Domain-Driven Design

Linguagem Omnipresente

Peritos de Domínio Programadores

Tradução complexa

Só nos entendemos se falarmos a mesma língua

“Alhos”

Page 19: Domain-Driven Design

Linguagem Omnipresente

Peritos de Domínio Programadores

Tradução complexa

“Bugalhos?”

Só nos entendemos se falarmos a mesma língua

“Alhos”

Page 20: Domain-Driven Design

Linguagem Omnipresente

Peritos de Domínio Programadores

Só nos entendemos se falarmos a mesma língua

“Alhos”

Page 21: Domain-Driven Design

MODELO

Linguagem Omnipresente

Peritos de Domínio Programadores

Só nos entendemos se falarmos a mesma língua

“Alhos”

Page 22: Domain-Driven Design

MODELO

Linguagem Omnipresente

Peritos de Domínio Programadores

Só nos entendemos se falarmos a mesma língua

“Alhos”

Page 23: Domain-Driven Design

MODELO

Linguagem Omnipresente

Peritos de Domínio Programadores

Só nos entendemos se falarmos a mesma língua

“Alhos”

Page 24: Domain-Driven Design

Linguagem Omnipresente

• O nosso Modelo sustenta a nossa linguagem

Experts de Domínio Programadores

Negócio

Código

MODELO

Page 25: Domain-Driven Design

Uma mesma linguagem para tudo

Nomes => ClassesVerbos => métodos, serviços, …Uma entidade empregadora coloca um anúncio de emprego:Classes: Job, JobBoardAcções: JobBoard.PostJob(Job)

O código também deve reflectir a linguagem.Exemplo:

Page 26: Domain-Driven Design

Bounded Context

• Em projectos grandes temos vários modelos em jogo

• É importante circunscrever o contexto ao qual o modelo se aplica– Explicitar fronteiras relativamente às diferentes

equipas envolvidas, espaços físicos e repositórios de código e de dados

– Preocupar-se apenas em garantir consistência dentro dessas fronteiras

Page 27: Domain-Driven Design

Continuous Integration

• Quanto maior é a equipa, maior é a tendência para fragmentar o modelo:– Instituir um processo de integração contínua que faça

merging do código e dos artefactos– Testes automatizados que detectem os erros ASAP

Page 28: Domain-Driven Design

Context Map

• Os contextos de outros modelos podem ser vagos e estar em permanente mudança– Identificar todos os modelos em jogo (inclusivé

subsistemas não object-oriented)– Dar nomes a esses contextos e fazer com que esses

nomes se tornem parte da nossa linguagem ubíqua– Identificar os pontos de contacto e desenhar

tradutores.

Page 29: Domain-Driven Design

Persistence Ignorance

Page 30: Domain-Driven Design

Ignorar a Persistência– Porquê?• Não queremos um modelo data-driven• Queremos liberdade na escolha do mecanismo de

persistência dos nossos dados• Facilitar os nossos testes unitários e a abordagem TDD

– Como?• Adoptar frameworks de acesso a dados “DDD-friendly”• Rejeitar ORMs estilo Active Objects • Usar ORMs pouco intrusivos (Ex: NHibernate, EF4)• Tirar partido dos Repositórios e Agregados

Page 31: Domain-Driven Design

Arquitectura DDD

Infrastructure

Domain Data Access

Application / Services

UI

Page 32: Domain-Driven Design

Arquitectura DDD– Infrastructure• Funcionalidades genéricas que suportam as camadas

superiores• Componentes de UI• Utilitários

– Domain• Lógica e regras • Estado do negócio• É o núcleo/coração da aplicação

Page 33: Domain-Driven Design

Arquitectura DDD– Application• Orquestrador, Serviços, Tarefas de negócio• Interacção com outros sistemas• Esta camada deve ser fina• Não deve ter regras nem conhecimentos do negócio• Não guarda o estado do negócio• Pode guardar estado do progresso de uma tarefa

– User Interface• Mostrar informação ao utilizador• Interpretar comandos

Page 34: Domain-Driven Design

Single Responsability Principle

Gerar PDF ImprimirUma classe deve ter apenas uma razão para sofrer mudanças.

Se tivermos 2 razões para mudar então deveremos separar em duas classes distintas.

Martin, Robert C. (2002). Agile Software Development, Principles, Patterns, and Practices

Page 35: Domain-Driven Design

Command and Query Responsibility Segregation

Diagrama de Mark Nijhof

AuditoriaBI

Agilidade

PerformanceSimplicidade

Commands Queries

Page 36: Domain-Driven Design

CQRS – Divisão de tarefas e rentabilidade

Diagrama de Mark Nijhof

Equipa de baixo custo produz código sem exigências de qualidade.Ideal para outsourcing.

Equipa especializadaem UI

Equipa pequenaaltamente

qualificada

Page 37: Domain-Driven Design

Command and Query Responsibility Segregation

• UI: Orientados à tarefa• Comandos: –Mudam o estado do domínio

• Event Store: –Armazena literalmente os eventos

• Query Store: Uma tabela por View (UI)– Exposta via SOA web services, WCF, WCF RIA

Page 38: Domain-Driven Design

Os blocos de código

Patterns

Page 39: Domain-Driven Design

Entidades

– São objectos definidos pela sua identidade (identificadores únicos)–A sua forma ou conteúdo podem mudar, mas a

identidade tem de ser preservada ao longo do ciclo de vida

Entidade

Page 40: Domain-Driven Design

Entidades

– São ainda definidos por:• Responsabilidades• Estrutura• Comportamentos

–A persistência nunca é responsabilidade da entidade (não usar entidades com métodos CRUD)

Page 41: Domain-Driven Design

Exemplo:

Cargo.csIEntity.cs

Page 42: Domain-Driven Design

Value Objects

– Imutáveis–Uma mesma instância pode ser usada em várias

entidades– Se queremos um valor diferente então criamos

uma nova instância– Exemplos: Moradas, Dinheiro, Códigos e até

identificadores de entidades

Page 43: Domain-Driven Design

Exemplo:

IValueObject.csItinerary.cs Leg.cs

Page 44: Domain-Driven Design

Agregados

Raíz do Agregado

Fronteira

Page 45: Domain-Driven Design

Agregados

É um agrupamento de objectos associados com os quais lidamos como se se tratassem de uma só unidade.–Dão consistência ao modelo–Definem relações de pertença–Definem fronteiras– Salvaguardam as invariantes (regras)

Page 46: Domain-Driven Design

Agregados

–Qualquer mudança de estado tem de garantir sempre as invariantes do agregado.– Fronteira• Separa o interior do exterior

–Raiz• É sempre uma Entidade• Responsável por garantir as invariantes• Pode ser livremente referenciada do exterior

Page 47: Domain-Driven Design

Agregados

–Os membros• Podem ser Entidades e Value Objects• Estas entidades apenas precisam de identidade

“local”• Os objectos exteriores não devem ver estes

membros fora do contexto da entidade raiz

Page 48: Domain-Driven Design

Nested Aggregates

–Quando o membro do agregado referencia a raiz de outro agregado– Evitar encadeamentos com demasiada

profundidade– Exemplo de encadeamento:• Agregado Job Board (membros: Job)• Agregado Job (membros: Skill, Applicant)• Agregado Applicant (membros: ApplicantSkill)

Page 49: Domain-Driven Design

Exemplo:

Cargo.cs Itinerary.cs Leg.cs Delivery.csRouteSpecification.cs

Agregado Cargo

Page 50: Domain-Driven Design

Factory

–Criar (e reconstruir) os objectos e agregados mais complexos– Encapsular a estrutura interna–Para objectos simples usar somente o

construtor é suficiente–Deve ser uma operação atómica–Garantir todas as invariantes

Page 51: Domain-Driven Design

Factory

–Diferentes tipos:• Standalone Factory• Factory Method– Util em aggregates– Situações em que temos um objecto com grande relação

de proximidade sobre o outro

• Abstract Factory• Builder (para fluent interfaces)

Page 52: Domain-Driven Design

Factory

– E as invariantes onde pertencem?• Pode-se delegar a validação ao próprio produto• Em agregados pode ser melhor ter as regras

também na própria factory (porque tipicamente estão dispersas por vários objectos)

–Regras do membro Identificador de uma entidade ou dum Value Object têm existir na Factory

Page 53: Domain-Driven Design

Exemplo:

Utilizamos internal no método construtor de Car para obrigar o projecto cliente a utilizar sempre a Factory na instanciação da classe Car.

Page 54: Domain-Driven Design

Repositório e Unit Of Work• Repositório–Abstrai o acesso aos dados– Funciona como uma colecção de objectos em

memória: Add, Remove, Get, Count• Unit Of Work–Registar as alterações ao estado dos objectos–Gerir as transacções: Commit, Rollback• ISession (NHibernate), DataContext (LinqToSQL)

Page 55: Domain-Driven Design

Citação...

«Leave transaction control to the client. (…) Transaction management will be simpler if the REPOSITORY keeps its hands off.»

Eric Evans

Page 56: Domain-Driven Design

Repositório

–Um por cada Agregado–O agregado é sempre devolvido válido e

completo–Abstrair a implementação• Facilitar os testes unitários• Maior liberdade para mudar a implementação• Facilitar optimizações de performance• Implementar mecanismos de caching

Page 57: Domain-Driven Design

Exemplo:

IUnitOfWork.csUnitOfWorkFactory.cs IRepository.cs IGenericRepository.cs

UnitOfWork.cs GenericRepository.csImplementação NHibernate

Page 58: Domain-Driven Design

Exemplo:

IUnitOfWork.csUnitOfWorkFactory.cs IRepository.cs IGenericRepository.cs

UnitOfWork.cs GenericRepository.csImplementação NHibernate

Page 59: Domain-Driven Design

Exemplo:

IUnitOfWork.csUnitOfWorkFactory.cs IRepository.cs IGenericRepository.cs

UnitOfWork.cs GenericRepository.csImplementação NHibernate

Page 60: Domain-Driven Design

Repository Per Aggregate– GetById(int id)– GetByName(string name)– GetByCityAndState(City city, State state)– Add(Person person)– Count(), Sum()

• Uma classe Repositório por cada Agregado• Dá-nos mais trabalho do que o repositório

genérico mas permite-nos afinar melhor as queries

Page 61: Domain-Driven Design

Generic Repository

• Uma classe genérica para todos os Agregados– GetById<TId>(TId id)– Query<T>(Expression<Func<T, bool>> query)– Insert<T>(T entity)– Delete<T>(T entity)

• Ex: new Repository<Person, int>(…)– GetById (20)– Query (p => p.Idade > 20)

Tipo Entidade

Tipo Identificador

Page 62: Domain-Driven Design

IQueryable com Paginação

Page 63: Domain-Driven Design

IQueryable com Paginação

Page 64: Domain-Driven Design

IQueryable com Paginação

Page 65: Domain-Driven Design

IQueryable com Paginação

Page 66: Domain-Driven Design

Specification• Pode ser usada para:– Validar um objecto e verificar se cumpre certos requisitos ou se

está preparado para um dado propósito– Seleccionar um objecto de uma colecção– Especificar as características de um objecto que vai ser

instanciado

• Podemos passar ao repositório com a especificação dos critérios de pesquisa traduzidos para a linguagem de acesso aos dados (SQL/Linq/NHibernate).

Page 67: Domain-Driven Design

Exemplo:

ISpecification.cs AbstractSpecification.cs

NotSpecification.csOrSpecification.cs

RouteSpecification.cs

Page 68: Domain-Driven Design

Resumo

– Entidade (Tem identidade)–Value Object (Imutável)–Aggregate (Garante consistência)– Factory (Facilita início do ciclo de vida)–Repository (Faz gestão da persistência)– Specification (Definir requisitos/características)

Page 69: Domain-Driven Design

Dúvidas?

Page 70: Domain-Driven Design

ReferênciasDomain-Driven Design: Tackling Complexity in the Heart of Software Eric Evans

Applying Domain-Driven Design and Patterns Jimmy Nilsson

Page 71: Domain-Driven Design

ReferênciasDomain Driven Design Community

– http://domaindrivendesign.org/

Apresentação Domain driven Design - Catapult Systems– http://www.slideshare.net/panesofglass/domain-driven-design

Unit Of Work - Martin Fowler– http://martinfowler.com/eaaCatalog/unitOfWork.html

Repositories and IQueryable, the paging case– http://thinkbeforecoding.com/post/2009/01/19/Repositories-and-IQueryabl

e-the-paging-case

CQRS: Recording of an online class – Greg Young– http://cqrsinfo.com/video/

Page 72: Domain-Driven Design

ReferênciasDDDSample (em Java)

– http://dddsample.sourceforge.net/

ndddsample (C# Domain Driven Design sample application)– http://code.google.com/p/ndddsample/

DDDSample .Net– http://dddsamplenet.codeplex.com/

Rhino Commons, Ayende Rahien– http://ayende.com/blog/archive/2007/06/08/rhino-commons-repositorylttgt

-and-unit-of-work.aspx

Page 74: Domain-Driven Design

Obrigado!

João [email protected]://blog.nicolauoliveira.comhttp://www.facebook.com/joaonoliveirahttp://pt.linkedin.com/in/jnicolau