Upload
steven-smith
View
449
Download
1
Embed Size (px)
Citation preview
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Introducing Domain-Driven Design (DDD)
@ardalis
Ardalis.com
Steve Smith
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Tweet Away!
• Live Tweeting and Photos are encouraged
• Questions and Feedback are welcome
• Use #Codemash and/or #DDDesign• (and mention @ardalis)
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Online Training
See me after for:
• 1-month free Pluralsight pass
• 20% off any DevIQ course
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
https://ardalis.com/architecture-ebook
http://microsoft.com/net/learn/architecture
Sample: https://github.com/dotnet-architecture/eShopOnWeb
Covers ASP.NET Core 2.x monolithic app developmentalong with several DDD principles and patterns.
Free Microsoft eBook
Starting down the path…
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
What is Domain-Driven Design?
Focus on the problem domainNot the database, or even the code implementation
Tools for better communication and knowledge discovery
Patterns for modeling solutionsWithout tight coupling to infrastructure concerns
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Some new thing?
Domain-Driven Design
published in 2004
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Why You Should Care about DDD
History ofsuccess with complex projects
Principles & patterns to solve difficultproblems
Clear, testable code that represents the domain
Aligns with practices from experts’ experience
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Flexible
Customer’s vision/perspective of the problem
Path through a very complex problem
Well-organized and easily tested code
Business logic lives in one place.
Many great patterns to leverage
Benefits of Domain Driven Design
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
While Domain-Driven Design provides many technical benefits, such as maintainability, it should be applied only to complex domains where the model and the linguistic processes provide clear benefits in the communication of complex information, and in the formulation of a common understanding of the domain.
—Eric EvansDomain-Driven Design
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Time and Effort
Learning curve (why you’re here)
Only makes sense when there is complexity in the problem
Team or Company Buy-In to DDD
Drawbacks of DDD
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
DDD Concepts
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
The Domain
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Core DomainYour company (or product/division)’s primary space in which they solve customers’ problems
Key differentiator
Problem DomainThe overall domain of the specific problem your application will address / solve
Generic SubdomainsSeparate applications or features your application must interact with. Not necessarily core to your app.
What are “domains”
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Domains refer to problem spaces.
Domain Models and Bounded Contexts are parts of a solution.
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Chapter
Bounded Contexts
Domain-Driven Design
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Appointment Scheduling
Bounded Context
Billing
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Explicitly define the context within which a model applies… Keep the model strictly consistent within these bounds, but don’t be distracted or confused by issues outside.
—Eric Evans
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Bounded Context
Appointment Scheduling Billing
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
What’s important to one bounded context may not be (as) important in another.
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Relates to the Solution you are building
The domain represents the problem your solution is solvingCore Domain – the business’s primary focus/industry
Sub-Domain – a particular area within a larger domain. Maps to a software solution and bounded context.
Bounded Context
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Context Maps
Client
Patient
Appointment
Notification
Exam Room
Client
Procedure Invoice
Notification
One DB To Rule Them All
Appointment Scheduler Billing
vet-managr
The Dev Team
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Context Maps
Client
Patient
Appointment
Notification
Exam Room
Client
Procedure Invoice
Notification
Appointment Scheduler Billing
DB DBAuthentication
User
Shared Kernel
vet-appt-sched
Team Awesome
vet-billing
Team Ultimate
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Ubiquitous Language
http://upload.wikimedia.org/wikipedia/commons/2/23/Rosetta_Stone.JPG
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
A project faces serious problems when its language is fractured.
—Eric Evans
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Ubiquitous Language
For a single Bounded Context
Used throughout that context, from conversations to code
Bounded Contexts should also have names, to aid in disambiguation.
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Problem DomainThe specific problem the software you’re working on is trying to solve.
Glossary of Terms
Core DomainThe key differentiator for the customer’s business – something they must do well and cannot outsource.
Sub-DomainsSeparate applications or features your software must support or interact with.
Bounded ContextA specific responsibility, with explicit boundaries that separate it from other parts of the system. Usually corresponds to a specific Sub-Domain.
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Context MappingThe process of identifying bounded contexts and their relationships to one another.
Glossary of Terms
Shared KernelPart of the model that is shared by two or more teams, who agree not to change it without collaboration
Ubiquitous LanguageA language using terms from the domain model that programmers and domain experts use to discuss the system within a particular bounded context.
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Chapter
The Domain Model
Domain-Driven Design
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
The Domain Model
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
BehaviorsSchedule an appointment for a checkupNote a pet’s weightRequest lab workNotify pet owner of vaccinations dueAccept a new patientBook a room
Not AttributesAppointment.Time Pet.Name Owner.Telephone Room.Number
FOCUS ON
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
RichDomainModelsAnemic
Domain Models
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
“The basic symptom of an Anemic Domain Model is that at first blush it looks like the real thing. There are objects, many named after the nouns in the domain space, and these objects are connected with the rich relationships and structure that true domain models have.
The catch comes when you look at the behavior, and you realize that there is hardly any behavior on these objects, making them little more than bags of getters and setters.”
—Martin Fowler
http://martinfowler.com/bliki/AnemicDomainModel.html
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Many objects are not fundamentally defined by their attributes, but rather by a thread of continuity and identity.
—Eric EvansDomain-Driven Design
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Entities Have Identity & Are Mutable
Jan 12 10:00 am
Check-Up
Snickerdoodle
AppointmentID=358
& Vaccinations
ID=172XXXX 9:30 am
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
ENTITIES
Entitiesin theNavigationMap
Evans,Domain-Driven Design, p. 65
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Entities should minimize direct access to their state (e.g. public property setters)
Encapsulate changes by exposing well-defined methodsEntities should be responsible for their own behavior
Be especially wary of collection properties!EF Core 1.1+ supports encapsulation of properties (exposing IEnumerable or ReadOnlyCollection)
Encapsulation
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Dependencies and Entities
Don’t inject dependencies into entity constructorsAnd of course don’t new up or call static infrastructure dependencies
This often leads to moving interesting behavior out of entities and into services
Consider raising domain eventsBehavior requiring dependencies shifts to domain event handlers
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
VALUE OBJECTS
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Value Object
Measures, quantifies, or describes a thing in the domain.
Identity is based on composition of values
Immutable
Compared using all values
No side effects
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Value Object Example
Company Worth: $50,000,000
$ 50,000,000
Worth (Value Object)
Monetary Unit (string) “U.S. Dollar”
Amount (decimal): 50000000
Company (Entity)
ID (guid): 9F63CE8D-9F1E-45E0-85AB-C098CC15F8E6
Worth Unit (string): “US Dollar”
Worth Amount (decimal): 50000000
Company (Entity)
ID (guid): 9F63CE8D-9F1E-45E0-85AB-C098CC15F8E6
Worth{Source:http://fit.c2.com/wiki.cgi?WholeValue (Ward Cunningham)
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
DateTimeRange
public class DateTimeRange{
public DateTimeRange(DateTime start, DateTime end){
Start=start;End=end;
}public DateTime Start { get; private set; }public DateTime End { get; private set; }…
}
Patient Appointment10:00 am Jan 4, 2014 – 11:00 am Jan 4, 2014
Staff Meeting2:00 pm Feb 1, 2014 – 3:15 pm Feb 1, 2014
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
It may surprise you to learn that we should strive to model using Value Objects instead of Entities wherever possible. Even when a domain concept must be modeled as an Entity, the Entity’s design should be biased toward serving as a value container rather than a child Entity container.
—Vaughn VernonImplementing Domain Driven Design
Patterns
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Aggregates
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Aggregates
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Aggregates
Customer
Address
Customer Aggregate
Product
Component
Product Aggregate
1
N N
1
Aggregate Root Aggregate Root
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Aggregates
Product
Component
Product Aggregate
N
1
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
An aggregate is a cluster of associated objects that we treat as a unit for the purpose of data changes.
—Eric EvansDomain-Driven Design
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Important operations that don’t belong to a particular Entity or Value Object
Good Domain Services:Not a natural part of an Entity or Value Object
Have an interface defined in terms of other domain model elements
Are stateless (but may have side effects)
Live in the Core of the application
Domain Services
Result
Value Object
Entity 2
Entity 1
Service
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Examples of Services in Different Layers
UI Layer& Application Layer
InfrastructureDomain(“Application Core”)
Message Sending
Message Processing
XML Parsing
UI Services
Transfer Between Accounts
Process Order
Send Email
Log to a File
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Repository
Palaeoclimate archives: Core repository of AWI Hannes Grobe/AWI Creative Commons Attribution 3.0
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
A repository represents all objects of a certain type as a conceptual set…like a collection with more elaborate querying capability.
—Eric EvansDomain-Driven Design
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
RepositoryBenefits
Provides common abstraction for persistence
Promotes Separation of Concerns
Communicates Design Decisions
Enables Testability
Improved Maintainability
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Client code can be ignorant of
repository implementation
…but developers cannot
N+1Query Errors
Inappropriate use of eager or
lazy loading
Fetching more data than required
Common Repository Blunders
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Enforce proper Aggregate usage by only creating Repositories for Aggregates
Use Marker Interfaces to identity Aggregate Roots
Constrain generic repository implementations to work with Aggregate Root types only
Repositories and Aggregates
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Avoid returning IQueryable results
Initially, use separate methods for specialized queries and commands
Address method explosion, SRP violation, and too much Repository complexity with the Specification pattern
Repository Method Tips
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Domain Events (one of my favorites)
Specification
Learn more about these from my Pluralsight courses:• DDD Fundamentals
• Design Patterns Library
Also check out Jimmy Bogard’s DDD talk at 12:15 today in Nile
More Patterns (we don’t have time for)
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Or tweet me @ardalis and I’ll answer later.
Let me know if I can help your team get up to speed with DDD, Clean Architecture, and/or .NET Core.
Questions?
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
No Content Here(Reserved for Watermark)
No Content Here(Reserved for Course Previews)
Thanks!
Follow us:
/DevIQPage
DevIQ.com/updates
@deviq• full-length courses • samples• member-only events
Enroll in DevIQ for access to:
DevIQ.com/enroll
Ardalis.com
@ardalis | [email protected]
Steve Smith
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Chapter
Decoupling with Domain Events
Domain-Driven Design
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Repositories ✓
Factories ✓
Services ✓
Entities ✓
Value Objects ✓
Aggregates ✓
Oh yeah, Domain Events
Usually the last kid picked from the DDD patterns I’m right
here!
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Domain Events not covered in original DDD book (2004)
Covered by Martin Fowler in 2005
Evans published article on them in 2010
Domain-Driven Design
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Application EventsPage Load, Button Click, Window Scroll
System EventsRestart, Backup Completed
Domain EventsAppointment Confirmed, Checkout Completed, Analysis Finished
Kinds of Events
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Given a customer has created an order
When the customer completes their purchase
Then the customer receives an email confirmation
An example scenario
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
OrderService
Checkout(Order order)
- Save pending order in database
- Send confirmation email
An example solution
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
So far, so good
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Given a customer has created an order
When the customer completes their purchase
Then the customer’s card is charged
And if it fails, send a different message to the customer
Then inventory is checked to ensure the order can be fulfilled
And if not a different message is sent to the customer
More requirements
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
OrderServiceCheckout(Order order)oAttempt to process payment
o If payment fails, send notification email; exit
oSave pending order in database
oConfirm inventory is available
o If insufficient email, send notification email; exit
oSend successful order confirmation email
An example solution
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Complexity is growing
Must change with each new requirementOpen/Closed Principle
Checkout’s responsibilities are growingSingle Responsibility Principle
Potentially different abstraction levels (emails, order processing rules)
Analysis
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
The Hollywood Principle
“Don’t Call Us, We’ll Call You”
See also Inversion of Control
Events allow other code to respond to something happening
Code initiating change doesn’t need to know about all follow-on activities
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
OrderService
Checkout(Order order)
- Dispatch new OrderCompletedEvent(order)
Event Handlers:
OrderPaymentHandler
OrderInventoryHandler
OrderNotificationHandler
An event-driven solution
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
An Event
Something that happened…that other parts of the application may need to know about
It’s a message…which should be immutable, since it represents the past
Usually asynchronous…especially across process boundaries
Event-Driven Programming
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
Model something that happens which is of interest to a domain expert
May lead to (or result from) a state change in a domain object
Are part of the domain model
Are usually handled synchronously within the application (but may themselves raise events outside of the application)
Domain Events
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
An event is raised
Handlers within the current process handle the event
If external applications need to be notified, specific handlers can adapt and send events to these applications as well
If unknown or future external applications will need to respond to events, a service bus can be implemented
Event Processing
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
How do you add logic to entities that affects multiple entities?
Example:
When a customer’s total amount purchased exceeds $1000, notify a salesperson to contact them.
Common Scenario
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
How do you add logic to entities that affects multiple entities?
Don’t solve this by using Dependency Injection on your entities. You should be able to easily instantiate entities without dependencies.
Avoid: Injecting Dependencies into Entities
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
How do you add logic to entities that affects multiple entities?
Don’t move logic that belongs within an entity into a service just because other entities are interested in what’s happening. This leads to the anemic domain model antipattern.
Only do this if the behavior spans multiple aggregates, in which case, the logic doesn’t belong to a particular entity or aggregate.
Avoid: Shifting Entity logic to Services
No Content Here(Reserved for Watermark)
Copyright © 2016, DevIQ, Inc.
How do you add logic to entities that affects multiple entities?
Raise a domain event to represent the action that took place.
Handle the domain event in a handler that collaborates with other entities.
Alternately, have the Aggregate Root register for events raised by members of its Aggregate.
Use Domain Events (and perhaps Aggregates)