83
No Content Here (Reserved for Watermark) Introducing Domain- Driven Design (DDD) @ardalis Ardalis.com Steve Smith

Introducing Domain Driven Design - codemash

Embed Size (px)

Citation preview

Page 1: Introducing Domain Driven Design - codemash

No Content Here(Reserved for Watermark)

Copyright © 2016, DevIQ, Inc.

Introducing Domain-Driven Design (DDD)

@ardalis

Ardalis.com

Steve Smith

Page 2: Introducing Domain Driven Design - codemash

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)

Page 3: Introducing Domain Driven Design - codemash

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

Page 4: Introducing Domain Driven Design - codemash

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

Page 5: Introducing Domain Driven Design - codemash

Starting down the path…

Page 6: Introducing Domain Driven Design - codemash

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

Page 7: Introducing Domain Driven Design - codemash

No Content Here(Reserved for Watermark)

Copyright © 2016, DevIQ, Inc.

Some new thing?

Domain-Driven Design

published in 2004

Page 8: Introducing Domain Driven Design - codemash

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

Page 9: Introducing Domain Driven Design - codemash

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

Page 10: Introducing Domain Driven Design - codemash

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

Page 11: Introducing Domain Driven Design - codemash

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

Page 12: Introducing Domain Driven Design - codemash

No Content Here(Reserved for Watermark)

Copyright © 2016, DevIQ, Inc.

DDD Concepts

Page 13: Introducing Domain Driven Design - codemash
Page 14: Introducing Domain Driven Design - codemash

No Content Here(Reserved for Watermark)

Copyright © 2016, DevIQ, Inc.

The Domain

Page 15: Introducing Domain Driven Design - codemash

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”

Page 16: Introducing Domain Driven Design - codemash

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.

Page 17: Introducing Domain Driven Design - codemash

No Content Here(Reserved for Watermark)

Copyright © 2016, DevIQ, Inc.

Chapter

Bounded Contexts

Domain-Driven Design

Page 18: Introducing Domain Driven Design - codemash

No Content Here(Reserved for Watermark)

Copyright © 2016, DevIQ, Inc.

Appointment Scheduling

Bounded Context

Billing

Page 19: Introducing Domain Driven Design - codemash

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

Page 20: Introducing Domain Driven Design - codemash

No Content Here(Reserved for Watermark)

Copyright © 2016, DevIQ, Inc.

Bounded Context

Appointment Scheduling Billing

Page 21: Introducing Domain Driven Design - codemash

No Content Here(Reserved for Watermark)

Copyright © 2016, DevIQ, Inc.

What’s important to one bounded context may not be (as) important in another.

Page 22: Introducing Domain Driven Design - codemash

No Content Here(Reserved for Watermark)

Copyright © 2016, DevIQ, Inc.

Page 23: Introducing Domain Driven Design - codemash

No Content Here(Reserved for Watermark)

Copyright © 2016, DevIQ, Inc.

Page 24: Introducing Domain Driven Design - codemash

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

Page 25: Introducing Domain Driven Design - codemash

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

Page 26: Introducing Domain Driven Design - codemash

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

Page 27: Introducing Domain Driven Design - codemash

No Content Here(Reserved for Watermark)

Copyright © 2016, DevIQ, Inc.

Ubiquitous Language

http://upload.wikimedia.org/wikipedia/commons/2/23/Rosetta_Stone.JPG

Page 28: Introducing Domain Driven Design - codemash

No Content Here(Reserved for Watermark)

Copyright © 2016, DevIQ, Inc.

A project faces serious problems when its language is fractured.

—Eric Evans

Page 29: Introducing Domain Driven Design - codemash

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.

Page 30: Introducing Domain Driven Design - codemash

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.

Page 31: Introducing Domain Driven Design - codemash

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.

Page 32: Introducing Domain Driven Design - codemash

No Content Here(Reserved for Watermark)

Copyright © 2016, DevIQ, Inc.

Chapter

The Domain Model

Domain-Driven Design

Page 33: Introducing Domain Driven Design - codemash

No Content Here(Reserved for Watermark)

Copyright © 2016, DevIQ, Inc.

Page 34: Introducing Domain Driven Design - codemash

The Domain Model

Page 35: Introducing Domain Driven Design - codemash

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

Page 36: Introducing Domain Driven Design - codemash

No Content Here(Reserved for Watermark)

Copyright © 2016, DevIQ, Inc.

RichDomainModelsAnemic

Domain Models

Page 37: Introducing Domain Driven Design - codemash

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

Page 38: Introducing Domain Driven Design - codemash

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

Page 39: Introducing Domain Driven Design - codemash

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

Page 40: Introducing Domain Driven Design - codemash

No Content Here(Reserved for Watermark)

Copyright © 2016, DevIQ, Inc.

ENTITIES

Entitiesin theNavigationMap

Evans,Domain-Driven Design, p. 65

Page 41: Introducing Domain Driven Design - codemash

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

Page 42: Introducing Domain Driven Design - codemash

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

Page 43: Introducing Domain Driven Design - codemash

No Content Here(Reserved for Watermark)

Copyright © 2016, DevIQ, Inc.

VALUE OBJECTS

Page 44: Introducing Domain Driven Design - codemash

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

Page 45: Introducing Domain Driven Design - codemash

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)

Page 46: Introducing Domain Driven Design - codemash

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

Page 47: Introducing Domain Driven Design - codemash

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

Page 48: Introducing Domain Driven Design - codemash

Patterns

Page 49: Introducing Domain Driven Design - codemash

No Content Here(Reserved for Watermark)

Copyright © 2016, DevIQ, Inc.

Aggregates

Page 50: Introducing Domain Driven Design - codemash

No Content Here(Reserved for Watermark)

Copyright © 2016, DevIQ, Inc.

Aggregates

Page 51: Introducing Domain Driven Design - codemash

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

Page 52: Introducing Domain Driven Design - codemash

No Content Here(Reserved for Watermark)

Copyright © 2016, DevIQ, Inc.

Aggregates

Product

Component

Product Aggregate

N

1

Page 53: Introducing Domain Driven Design - codemash

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

Page 54: Introducing Domain Driven Design - codemash

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

Page 55: Introducing Domain Driven Design - codemash

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

Page 56: Introducing Domain Driven Design - codemash

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

Page 57: Introducing Domain Driven Design - codemash

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

Page 58: Introducing Domain Driven Design - codemash

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

Page 59: Introducing Domain Driven Design - codemash

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

Page 60: Introducing Domain Driven Design - codemash

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

Page 61: Introducing Domain Driven Design - codemash

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

Page 62: Introducing Domain Driven Design - codemash

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)

Page 63: Introducing Domain Driven Design - codemash

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?

Page 64: Introducing Domain Driven Design - codemash

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

Page 65: Introducing Domain Driven Design - codemash

No Content Here(Reserved for Watermark)

Copyright © 2016, DevIQ, Inc.

Chapter

Decoupling with Domain Events

Domain-Driven Design

Page 66: Introducing Domain Driven Design - codemash

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!

Page 67: Introducing Domain Driven Design - codemash

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

Page 68: Introducing Domain Driven Design - codemash

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

Page 69: Introducing Domain Driven Design - codemash

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

Page 70: Introducing Domain Driven Design - codemash

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

Page 71: Introducing Domain Driven Design - codemash

No Content Here(Reserved for Watermark)

Copyright © 2016, DevIQ, Inc.

So far, so good

Page 72: Introducing Domain Driven Design - codemash

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

Page 73: Introducing Domain Driven Design - codemash

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

Page 74: Introducing Domain Driven Design - codemash

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

Page 75: Introducing Domain Driven Design - codemash

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

Page 76: Introducing Domain Driven Design - codemash

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

Page 77: Introducing Domain Driven Design - codemash

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

Page 78: Introducing Domain Driven Design - codemash

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

Page 79: Introducing Domain Driven Design - codemash

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

Page 80: Introducing Domain Driven Design - codemash

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

Page 81: Introducing Domain Driven Design - codemash

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

Page 82: Introducing Domain Driven Design - codemash

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

Page 83: Introducing Domain Driven Design - codemash

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)