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.
6. Release Manager na Solutions FactoryC# ASP.Net WPF WCF DNN jQuery Delphi Java Zope
7. 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.» EricEvans
8. Agenda O que é? Quando usar? Como? UbiquousLanguage, BoundedContexts, Integração Contínua, ContextMap, PersistenceIgnorance Command and Query Responsability Segregation Patterns: ValueObject, Entity, Aggregate, Factory, Repository, UnitOfWork, Specification
10. 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.
12. O que é o modelo do domínio? É umarepresentação
13. 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.
14. 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
15. Modelar - Como? Processo de melhoria, ajuste, adaptação, aprendizagem, experimentação Modelos Emergentes Linguagem Omnipresente
17. Linguagem Omnipresente Só nos entendemos se falarmos a mesma língua Peritos de Domínio Programadores
18. Linguagem Omnipresente Só nos entendemos se falarmos a mesma língua Peritos de Domínio Programadores
19. Linguagem Omnipresente Só nos entendemos se falarmos a mesma língua Peritos de Domínio Programadores
20. Linguagem Omnipresente Só nos entendemos se falarmos a mesma língua Peritos de Domínio Programadores “Alhos”
21. Linguagem Omnipresente Só nos entendemos se falarmos a mesma língua Peritos de Domínio Programadores Tradução complexa “Alhos”
22. Linguagem Omnipresente Só nos entendemos se falarmos a mesma língua Peritos de Domínio Programadores Tradução complexa “Bugalhos?” “Alhos”
23. Linguagem Omnipresente Só nos entendemos se falarmos a mesma língua Peritos de Domínio Programadores “Alhos”
24. Linguagem Omnipresente Só nos entendemos se falarmos a mesma língua Peritos de Domínio Programadores MODELO “Alhos”
25. Linguagem Omnipresente Só nos entendemos se falarmos a mesma língua Peritos de Domínio Programadores MODELO “Alhos”
26. Linguagem Omnipresente Só nos entendemos se falarmos a mesma língua Peritos de Domínio Programadores MODELO “Alhos”
27. Linguagem Omnipresente O nosso Modelo sustenta a nossa linguagem Experts de Domínio Programadores Negócio MODELO Código
28. Uma mesma linguagem para tudo O código também deve reflectir a linguagem. Exemplo: Nomes => Classes Verbos => métodos, serviços, … Uma entidade empregadora coloca um anúncio de emprego: Classes: Job, JobBoard Acções: JobBoard.PostJob(Job)
29. 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
30. 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
31. 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.
33. 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
35. 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
36. 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
37. Single ResponsabilityPrinciple Uma 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. Imprimir Gerar PDF Martin, Robert C. (2002). Agile Software Development, Principles, Patterns, andPractices
38. Command and Query Responsibility Segregation Performance Simplicidade Auditoria BI Agilidade Commands Queries Diagrama de Mark Nijhof
39. CQRS – Divisão de tarefas e rentabilidade Equipa de baixo custo produz código sem exigências de qualidade. Ideal para outsourcing. Equipa pequena altamentequalificada Diagrama de Mark Nijhof Equipa especializada em UI
40. 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
42. 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
43. Entidades São ainda definidos por: Responsabilidades Estrutura Comportamentos A persistência nunca é responsabilidade da entidade (não usar entidades com métodos CRUD)
45. ValueObjects 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
48. 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)
49. 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
50. Agregados Os membros Podem ser Entidades e ValueObjects Estas entidades apenas precisam de identidade “local” Os objectos exteriores não devem ver estes membros fora do contexto da entidade raiz
51. NestedAggregates 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)
53. 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
54. Factory Diferentes tipos: StandaloneFactory FactoryMethod Util em aggregates Situações em que temos um objecto com grande relação de proximidade sobre o outro AbstractFactory Builder (para fluent interfaces)
55. 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 ValueObjecttêm existir na Factory
56. Exemplo: Utilizamos internalno método construtor de Car para obrigar o projecto cliente a utilizar sempre a Factory na instanciação da classe Car.
57. Repositório e UnitOfWork Repositório Abstrai o acesso aos dados Funciona como uma colecção de objectos em memória: Add, Remove, Get, Count UnitOfWork Registar as alterações ao estado dos objectos Gerir as transacções: Commit, Rollback ISession (NHibernate), DataContext (LinqToSQL)
58. Citação... «Leave transaction control to the client. (…) Transaction management will be simpler if the REPOSITORY keeps its hands off.» Eric Evans
59. 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
63. RepositoryPerAggregate GetById(int id) GetByName(string name) GetByCityAndState(City city, State state) Add(Person person) Count(), Sum() Uma classeRepositórioporcadaAgregado Dá-nosmaistrabalho do que o repositóriogenéricomaspermite-nosafinarmelhor as queries
64. GenericRepository Uma classe genérica para todos os Agregados GetById<TId>(TIdid) Query<T>(Expression<Func<T, bool>> query) Insert<T>(T entity) Delete<T>(T entity) Ex: newRepository<Person, int>(…) GetById (20) Query (p => p.Idade > 20) Tipo Entidade Tipo Identificador
69. 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).
73. Referências Domain-Driven Design: Tackling Complexity in the Heart of Software Eric Evans Applying Domain-Driven Design and Patterns Jimmy Nilsson
74. Referências DomainDriven Design Community http://domaindrivendesign.org/ Apresentação Domaindriven Design - CatapultSystems http://www.slideshare.net/panesofglass/domain-driven-design UnitOfWork - MartinFowler http://martinfowler.com/eaaCatalog/unitOfWork.html Repositories and IQueryable, the paging case http://thinkbeforecoding.com/post/2009/01/19/Repositories-and-IQueryable-the-paging-case CQRS: Recording of an online class – Greg Young http://cqrsinfo.com/video/
77. Obrigado! João Oliveira joao@nicolauoliveira.com http://blog.nicolauoliveira.com http://www.facebook.com/joaonoliveira http://pt.linkedin.com/in/jnicolau
Notas do Editor
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 usar e como implementar. Para além disso serão apresentadas as principais Patterns acompanhadas com exemplos práticos de código.