pursuing practices of domain-driven design in php
DESCRIPTION
TRANSCRIPT
![Page 1: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/1.jpg)
Pursuingpractices of
Domain-DrivenDesignin PHP
![Page 2: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/2.jpg)
Who am I
Giorgio SironiBachelor in Computer
EngineeringAdvisor @ Allbus
Zone Leader @ DZone
![Page 3: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/3.jpg)
The long title
Pursuingpractices of
Domain-DrivenDesignin PHP
![Page 4: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/4.jpg)
The DDD box of goods
Knowledge crunching
Ubiquitous Language
Domain Model
Refactoring towards deeper insight...
Collaboration patterns (Anti-corruption layer, Separate ways, ...)
![Page 5: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/5.jpg)
Why? (the most important slide)
Close to business, to follow its changes
aids iterative development
The code is the design
supported by blackboards and UML
Test and develop with in-memory objects
no instantiation of Oracle connections
It's also fun!
exercise creativity and learning skills
![Page 6: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/6.jpg)
Domain Model
Reflects knowledge of the domain more than technology
While there is value in the item on the right, we value the item on the left more
Persistence-agnostic (UnitOfWork)
In general, no outward dependencies
![Page 7: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/7.jpg)
Step 1: from relational...
user
id
username
password
active
user_group
id_user
id_group
group
id
name
logo
![Page 8: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/8.jpg)
Step 1: ...to object-oriented
class User{}
class Group{}
![Page 9: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/9.jpg)
Step 2: from Active Record...
class Group extends Doctrine_Record
{
}
Hard dependency towards ORM
Inherits pollution from Doctrine_Record
![Page 10: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/10.jpg)
Step 2: … to Data Mapper
/**
* @Entity
*/
class User
{
}
![Page 11: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/11.jpg)
Building blocks
Entity
Value Object
Aggregate
Repository
Factory
Service
Other transient objects (Specification, Parameter Objects, ...)
![Page 12: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/12.jpg)
Entity
More than a row
Equality is based on identity
e.g. Post #42, user 'giorgiosironi', …
The bread and butter of your Domain Model
![Page 13: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/13.jpg)
Value Object
Previously known in the world as value
e.g. the number 42, Zip code 22031, #FF0000
Equality based on values
Immutable in certain implementations
![Page 14: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/14.jpg)
Aggregate
Subgraph of Entities and Value Objects
with a single entry: the root
possible multiple exits, mostly to follow during reading
Unit of consistency: loose correspondency to database transactions
Partitions the state of the application
![Page 15: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/15.jpg)
Checkpoint: data modeling
![Page 16: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/16.jpg)
Repository
The gate to the database
One aggregate at the time
The illusion of an in-memory collection of Entities
Fowler's definition
Here's a BookRepository
![Page 17: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/17.jpg)
Factory
Encapsulate creation of complex Aggregates
a new() is often all you need
![Page 18: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/18.jpg)
Service
At the domain level
To help Entities and Value Objects
to avoid mutual dependencies
or field references to strangersoptimal for isolation from libraries
![Page 19: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/19.jpg)
Checkpoint: lifecycle classes
![Page 20: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/20.jpg)
Meanwhile, in PHP...
![Page 21: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/21.jpg)
On frameworks
Only one suggestion: build your Domain Model like if the framework didn't exist
![Page 22: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/22.jpg)
Active Record vs. Data Mapper
Doctrine 2 for persistence (see tutorial by @juokaz)
By default for Doctrine 2 object === row
All the tricks are at http://github.com/giorgiosironi/ddd-talk
![Page 23: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/23.jpg)
Entity
@Entity annotation
no extends
@Column for fields
private fields
types are PHP types: string, not varchar
![Page 24: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/24.jpg)
Value Objects
Do you want an (id, date) table?
Serialization of the whole object
Conversion into a custom string/numerical format via a custom DBAL data type
Deconstruction/reconstruction with lifecycle hooks
Combined approaches: serialization and mirror fields
![Page 25: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/25.jpg)
Aggregate
Relationships: @OneToMany, @ManyToMany, @OneToOne, …
● @OneToMany(..., cascade={“persist”, “remove”})
● @OneToMany(..., orphanRemoval=true)● @ManyToMany(targetEntity="Phonenumber") @JoinTable(..., inverseJoinColumns={name=”phonenumber_id", referencedColumnName="id", unique=true)
![Page 26: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/26.jpg)
Repository
Plain Old PHP Object
Composing EntityManager
It's possible to define EntityManager custom repositories: quick and dirty
Encapsulates queries
Typical methods: add($root), remove($root), find($id), findByStrangeCriteria()
It's a collection!
![Page 27: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/27.jpg)
Factory, Service
POPO
Sometimes composing services or infrastructure objects (e.g. generating new progressive number for invoices, calculate current taxes, sending mails...)
Often decoupled with an interface
![Page 28: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/28.jpg)
References
The code shown in this talk
http://github.com/giorgiosironi/ddd-talk
Four books
http://domaindrivendesign.org/books
Domain-Driven Design mailing list
Google that :)
![Page 29: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/29.jpg)
Q/A
![Page 30: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/30.jpg)
Testing in isolation tutorial: http://joind.in/3216
DDD talk: http://joind.in/3224
Feedback
![Page 31: Pursuing practices of Domain-Driven Design in PHP](https://reader034.vdocuments.us/reader034/viewer/2022051513/5455b0a1b1af9f40378b49ae/html5/thumbnails/31.jpg)
Thanks for your attention