DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The...

64
DDD for Beginners Rob Allen @akrabat ~ January 2017 ~ http://akrabat.com

Transcript of DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The...

Page 1: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

DDD for BeginnersRob Allen

   

@akrabat ~ January 2017 ~ http://akrabat.com

Page 2: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

The business logicis the hard part

Rob Allen ~ @akrabat

Page 3: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

MVC

Rob Allen ~ @akrabat

Page 4: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

MVC

Rob Allen ~ @akrabat

Page 5: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

DDD is an approach to helpyou manage the model

Rob Allen ~ @akrabat

Page 6: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Domain Driven DesignA set of patterns for the model:

• Language• Strategy• Tactical

Rob Allen ~ @akrabat

Page 7: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

DomainThe domain is the "real-world" subject of the projectThe model is an abstraction of the domain

We communicate the model using:

• diagrams• use-cases• specifications• etc.

Rob Allen ~ @akrabat

Page 8: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Is DDD the right choice?DDD requires time, effort and collaboration with the business experts.Benefits:

• Useful model of the problem domain• Collaboration between the business & the software teams• Better user experiences with the software• Better architecture through better understanding

Rob Allen ~ @akrabat

Page 9: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

"We have really everything in common with Americanowadays except, of course, language"

Oscar Wilde

Rob Allen ~ @akrabat

Page 10: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Ubiquitous Language• A common language between the developers and the business• Limited to how the domain problem• Describes how business itself thinks and operates• Ensures that the team are all on the same page

The UL is the agreed concepts, meanings and terms for the project.

Rob Allen ~ @akrabat

Page 11: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Creating the Ubiquitous LanguageConversations in the team exploring how the business operates.

• Identify the business processes• Find the inputs and outputs• Document it all! pictures, use-cases, glossary, workflow diagrams,

etc.

Rob Allen ~ @akrabat

Page 12: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Bounded Contexts & Context MapsThe context where our UL is valid is called the Bounded ContextInsurance example:

• Quotation• Policies• Underwriting• Billing• Customer management

Rob Allen ~ @akrabat

Page 13: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Putting it into practice

Rob Allen ~ @akrabat

Page 14: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

What's in the model?

Rob Allen ~ @akrabat

Page 15: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Organising the model

Rob Allen ~ @akrabat

Page 16: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

A problemA customer wants to plan a journey between two stations.

Rob Allen ~ @akrabat

Page 17: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

How do we model this?

Rob Allen ~ @akrabat

Page 18: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Identify the key objects• Customer• Journey• Station• Line

Rob Allen ~ @akrabat

Page 19: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Identify the relationships

Rob Allen ~ @akrabat

Page 20: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Entities represent things in theproblem-space

Rob Allen ~ @akrabat

Page 21: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Entity• Means something to the customer• An object defined primarily by its identity• Mutable• Persisted• Has a life cycle

Rob Allen ~ @akrabat

Page 22: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Identity• The identity of an object is what it means to the customer• Unique within the scope of the domain

For a tube station, this is as much its name, as its database ID.My customer is never going to talk to me about station 43, they aregoing to say "Euston Square".

Rob Allen ~ @akrabat

Page 23: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Value objects• Defined primarily by its attributes• Immutable• Simple!• Do not exist without an entity

Rob Allen ~ @akrabat

Page 24: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Entity vs Value Object“When people exchange dollar bills, they generally do notdistinguish between each unique bill; they only are concernedabout the face value of the dollar bill. In this context, dollar bills arevalue objects.However, the Federal Reserve may be concerned about eachunique bill; in this context each bill would be an entity.”

Wikipedia

Rob Allen ~ @akrabat

Page 25: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

AggregatesA group of Entities and Value objects that need to be consistent whenpersisted.Example:

• Order• Line item

Rob Allen ~ @akrabat

Page 26: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

A station has a location

Rob Allen ~ @akrabat

Page 27: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

A station has a location

Rob Allen ~ @akrabat

Page 28: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Domain servicesIf a SERVICE were devised to make appropriate debits and creditsfor a funds transfer, that capability would belong in the domainlayer.

Eric Evans

Rob Allen ~ @akrabat

Page 29: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Domain services• We map the business processes to services• Represents behaviour in the domain• A service does not have internal state• Usually a point of connection for many objects

Rob Allen ~ @akrabat

Page 30: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Domain servicesConditions for using a domain service:

• Calculations requiring input from multiple domain objects• Performing a significant business process• Transforming a domain object from one composition to another

Rob Allen ~ @akrabat

Page 31: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Let's look at some code

Rob Allen ~ @akrabat

Page 32: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

An entity 1 class Journey { 2 function getStart() {} 3 function setStart(Station $start) {} 4

5 function getStop() {} 6 function setStop(Station $stop) {} 7

8 function getRoute() {} 9 function setRoute(Route $route) {}10 }

Rob Allen ~ @akrabat

Page 33: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

A service1 class RoutingService {2 pubic function calculateRoute(Station $from, Station $to) : Route {}3 }

Rob Allen ~ @akrabat

Page 34: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Anaemic domain modelWhen you look at the behavior, and you realize that there is hardlyany behavior on these objects, making them little more than bagsof getters and setters.Instead there are a set of service objects which capture all thedomain logic.

Martin Fowler

Rob Allen ~ @akrabat

Page 35: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Entity with behaviour1 class Journey {2 public function __construct (Station $from, Station $to) {}3

4 public function calculateRoute() : Route {}5 }

Rob Allen ~ @akrabat

Page 36: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

What happens if calculateRoute()is complex?

Rob Allen ~ @akrabat

Page 37: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Implement as a helperThe entity calls the helper, passing a reference to itself. 1 // Helper class

2 class JourneyRouter { 3 public function calculateRoute(Journey $journey) : Route {} 4 }

5

6 // Journey class

7 class Journey { 8 function calculateRoute() : Route { 9 $route = $this->journeyRouter->calculateRoute($this);

10 }

11 }

Rob Allen ~ @akrabat

Page 38: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Persistence

Rob Allen ~ @akrabat

Page 39: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Persistence optionsA simple domain model can use TDG or Data Mapper;a complex one will require Data Mapper or an ORM.Aggregates need an ORM

Pick the right one!

Rob Allen ~ @akrabat

Page 40: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

But don't use ActiveRecord pattern!

Rob Allen ~ @akrabat

Page 41: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

But don't use ActiveRecord pattern!It integrates the database code into your domain model

Rob Allen ~ @akrabat

Page 42: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Table Data Gateway• Operates on a single database table• Contains all the SQL for accessing the table• Doesn't know anything about the entity• Simple to implement

Rob Allen ~ @akrabat

Page 43: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Table Data Gateway1 class JourneyGateway {2 function __construct($dbAdapter) {}3

4 function find($id) {}5 function findForStartingStation($stationId) {}6

7 function insert(array $data) {}8 function update($id, array $data) {}9 }

Rob Allen ~ @akrabat

Page 44: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Data Mapper• Class to transfer data from objects to the database and back• Entity aware• Isolates the domain model from the database• Not limited to a single table

Rob Allen ~ @akrabat

Page 45: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Data Mapper1 class JourneyMapper {2 function __construct($dsn, $username, $password) {}3

4 function find($id) : Journey {}5 function findForStartingStation($stationId) : [Journey] {}6

7 public function save(Journey $journey) {}8 }

Rob Allen ~ @akrabat

Page 46: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Increased scope: ORMData mapping that works with the object graphs is known as anObject Relational MappingMust-have for aggregates, but use a pre-written ORM library!

Rob Allen ~ @akrabat

Page 47: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

ORMPersistence layer is more complicated:

• Storage of entire object graphs to the database• Identity map to hold loaded objects• Unit of Work to track changed objects for saving

Rob Allen ~ @akrabat

Page 48: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Repositories• 1-1 relationship between repository and aggregate• Manage the loading and storing of aggregates• Often oriented around collections of aggregates

Rob Allen ~ @akrabat

Page 49: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Web services• The persistence storage could be a web service• Data mappers work really well

Rob Allen ~ @akrabat

Page 50: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Integrating our model into theapplication

Rob Allen ~ @akrabat

Page 51: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

The application layer*It does not contain business rules or knowledge, but onlycoordinates tasks and delegates work to collaborations of domainobjects in the next layer down.

Eric Evans

      * (Known as service layer in PoEAA)

Rob Allen ~ @akrabat

Page 52: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Application layerWe can sub-divide:

• Application services• Infrastructural services

Rob Allen ~ @akrabat

Page 53: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Application servicesIf the banking application can convert and export our transactionsinto a spreadsheet file for us to analyze, this is an applicationSERVICE.

Eric Evans

Rob Allen ~ @akrabat

Page 54: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Application service 1 class JourneyCreator { 2 public function createJourney(Customer $customer, Station $from, Station $to) 3 {

4 $journey = $customer->createJourney($from, $to);

5 $journey->calculateRoute();

6

7 $this->notifier->send($journey);

8 $this->auditor->log("Journey created", $journey);

9 }

10 }

Rob Allen ~ @akrabat

Page 55: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Beware the Fat serviceDecouple using Observer pattern

Rob Allen ~ @akrabat

Page 56: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Infrastructural servicesA bank might have an application that sends out an email to acustomer when an account balance falls below a specificthreshold. The interface that encapsulates the email system, andperhaps alternate means of notification, is a SERVICE in theinfrastructure layer.

Eric Evans

Rob Allen ~ @akrabat

Page 57: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Infrastructural service• Standard: there's no business or application logic• Reusable across applications• Do not write your own - this is what the ecosystem is for

Rob Allen ~ @akrabat

Page 58: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

To sum up

Rob Allen ~ @akrabat

Page 59: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

To sum upUbiquitous Language:

Agreed vocabulary with the businessBounded Context:

Area of the problem space where the Ubiquitous Language is valid

Rob Allen ~ @akrabat

Page 60: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

To sum upEntity:

Object with identity that do stuffValue object:

Immutable with no identityDomain service:

Behaviours that don't belong to an entity

Rob Allen ~ @akrabat

Page 61: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

To sum upMappers / Repository:

Transfer your model to and from persistenceApplication services:

Isolate your domain model from your controllersInfrastructure services:

Support services for your application

Rob Allen ~ @akrabat

Page 62: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Final point

Rob Allen ~ @akrabat

Page 63: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

The success of a design is not necessarily marked byits longevity. It is the nature of software to change.

Eric Evans

Rob Allen ~ @akrabat

Page 64: DDD for Beginners - akrabat.com · DDD for Beginners Rob Allen @ ... Domain Driven Design ... The entity calls the helper, passing a reference to itself. 1 // Helper class 2 class

Thank you!  

Please rate this talk on EventsXD 

Rob Allen ~ @akrabat ~ akrabat.com