Domain Driven Design
Josh Dastmalchi
Let’s Drive a Manual Car
How do we shift gears?
• Press the clutch pedal to the floor
• Use the gear shift to change gears
• Depress the clutch pedal while also pressing the gas pedal
Okay, Let’s Drive!
The Importance of Why, What, When
Priorities
Correctness
• If it doesn’t do what we intended, we have failed.
• Testability – how do I know I’m correct?
Ease of Change
• Software is never done.
• An anecdote: “This requirement will definitely never change”
Methods
Ubiquitous Language
• To achieve correctness, we must communicate the product needs.
• If we're not speaking the same language, we're off to a bad start.
• What if we all had different native languages?
The Boot
Contextless Truth
• The truth of a domain exists outside of any user interface or database.
• Use Cases:
• The domain defines truth - what is possible in reality
• A use case defines what is possible in the application
Patterns
• Establishing patterns takes the mystery away from doing common tasks.
• Command-Query Responsibility Segregation
• Repository
• Hexagonal
The Code
What everyone really wants to see
Domain Events
Represents a change of state in our domain.
• All domain mutations produce domain events recording them.
• Event handlers can listen for these events and perform actions accordingly
• Enables event sourcing, a powerful but complex way to store domain history.
Domain Events: My experience
• They won’t feel useful initially – but they unlock a lot of power for later
complexity.
• Generally there are two types of handlers:
• Handlers that enforce domain rules of the form “When x, then y”
• Handlers that inform other systems of changes in our domain
• Include enough information in events to make them reversible
• Prefer domain services or entities to event handlers
Entities
Represents a concept in our domain.
• Has an immutable unique identifier.
• Enforces invariants (domain rules) and never allows itself to be in an invalid state.
Aggregates
Aggregates are a special type of entity.
• An aggregate cannot be nested in another entity's object graph.
• An aggregate can be referenced by ID by another entity.
• Non-aggregate entities do not track events.
• Non-aggregate entities do not have public methods.
Aggregates: My Experience
• Minimize aggregate size.
• (Almost) never use non-aggregate entities.
Value Objects
Represents a complex property in our domain.
• In contrast to entities, equality is determined by a value object’s properties, not a
unique identifier.
• Like entities, these are self-validating.
Value Objects: My Experience
• For primitive types, always consider wrapping them in a value object.
• If an entity has complex validation across multiple properties, consider wrapping
them all together as a value object.
• Wrapping your aggregate identifiers as value objects provides type safety in a
place where it is very easy to make mistakes.
Domain Service
• An implementation of orchestrated domain logic that can’t be put on an
aggregate
• Common reasons to use a service:
• Uniqueness checks
• Configuration-based logic
• Interaction with multiple aggregates
Domain Services: My Experience
• Use single-purpose services and composition instead of large services
• Avoid an anemic domain: prefer entity-based logic over service-based logic
• If an entity method requires service orchestration, use access modifiers to prevent
non-domain calls
Major Takeaways: Why
Priorities
1. Correctness
2. Ease of change
Methods
• Ubiquitous language
• Contextless truth
Major Takeaways: How
• Domain design: Correctness & Ease of Change
• Domain logic: Entity > Service > Event Handler
• Small entities, small services
Live Demo
Real Practice – Adapting the Domain
• A doctor’s name must be at least 3 characters, can be no more than 50 characters, and
must consist of only alphanumeric characters.
• An appointment can only be scheduled in increments of 15 minutes. Specifically,
appointment times must end in :00, :15, :30, or :45.
• Doctors get days off – holidays, time off, etc. We should add a concept of a doctor’s
time off that specifies a date and hours on that date during which a doctor is
unavailable. This should prevent appointments being scheduled during that time and
delete any existing appointments during that time. Time off should only be able to be
scheduled in the future.
Links
• Source Code: https://github.com/josh-dastmalchi/ddd-example

Domain Driven Design Belfast Meetup - Overview, Lessons and Examples by Josh Dastmalchi

  • 1.
  • 2.
    Let’s Drive aManual Car
  • 3.
    How do weshift gears? • Press the clutch pedal to the floor • Use the gear shift to change gears • Depress the clutch pedal while also pressing the gas pedal
  • 4.
  • 5.
    The Importance ofWhy, What, When
  • 6.
  • 7.
    Correctness • If itdoesn’t do what we intended, we have failed. • Testability – how do I know I’m correct?
  • 8.
    Ease of Change •Software is never done. • An anecdote: “This requirement will definitely never change”
  • 9.
  • 10.
    Ubiquitous Language • Toachieve correctness, we must communicate the product needs. • If we're not speaking the same language, we're off to a bad start. • What if we all had different native languages?
  • 11.
  • 12.
    Contextless Truth • Thetruth of a domain exists outside of any user interface or database. • Use Cases: • The domain defines truth - what is possible in reality • A use case defines what is possible in the application
  • 13.
    Patterns • Establishing patternstakes the mystery away from doing common tasks. • Command-Query Responsibility Segregation • Repository • Hexagonal
  • 14.
    The Code What everyonereally wants to see
  • 15.
    Domain Events Represents achange of state in our domain. • All domain mutations produce domain events recording them. • Event handlers can listen for these events and perform actions accordingly • Enables event sourcing, a powerful but complex way to store domain history.
  • 18.
    Domain Events: Myexperience • They won’t feel useful initially – but they unlock a lot of power for later complexity. • Generally there are two types of handlers: • Handlers that enforce domain rules of the form “When x, then y” • Handlers that inform other systems of changes in our domain • Include enough information in events to make them reversible • Prefer domain services or entities to event handlers
  • 19.
    Entities Represents a conceptin our domain. • Has an immutable unique identifier. • Enforces invariants (domain rules) and never allows itself to be in an invalid state.
  • 20.
    Aggregates Aggregates are aspecial type of entity. • An aggregate cannot be nested in another entity's object graph. • An aggregate can be referenced by ID by another entity. • Non-aggregate entities do not track events. • Non-aggregate entities do not have public methods.
  • 28.
    Aggregates: My Experience •Minimize aggregate size. • (Almost) never use non-aggregate entities.
  • 29.
    Value Objects Represents acomplex property in our domain. • In contrast to entities, equality is determined by a value object’s properties, not a unique identifier. • Like entities, these are self-validating.
  • 35.
    Value Objects: MyExperience • For primitive types, always consider wrapping them in a value object. • If an entity has complex validation across multiple properties, consider wrapping them all together as a value object. • Wrapping your aggregate identifiers as value objects provides type safety in a place where it is very easy to make mistakes.
  • 36.
    Domain Service • Animplementation of orchestrated domain logic that can’t be put on an aggregate • Common reasons to use a service: • Uniqueness checks • Configuration-based logic • Interaction with multiple aggregates
  • 43.
    Domain Services: MyExperience • Use single-purpose services and composition instead of large services • Avoid an anemic domain: prefer entity-based logic over service-based logic • If an entity method requires service orchestration, use access modifiers to prevent non-domain calls
  • 44.
    Major Takeaways: Why Priorities 1.Correctness 2. Ease of change Methods • Ubiquitous language • Contextless truth
  • 45.
    Major Takeaways: How •Domain design: Correctness & Ease of Change • Domain logic: Entity > Service > Event Handler • Small entities, small services
  • 46.
  • 47.
    Real Practice –Adapting the Domain • A doctor’s name must be at least 3 characters, can be no more than 50 characters, and must consist of only alphanumeric characters. • An appointment can only be scheduled in increments of 15 minutes. Specifically, appointment times must end in :00, :15, :30, or :45. • Doctors get days off – holidays, time off, etc. We should add a concept of a doctor’s time off that specifies a date and hours on that date during which a doctor is unavailable. This should prevent appointments being scheduled during that time and delete any existing appointments during that time. Time off should only be able to be scheduled in the future.
  • 48.
    Links • Source Code:https://github.com/josh-dastmalchi/ddd-example