SlideShare a Scribd company logo
Domain-Driven Design 
in PHP & Symfony
Kacper Gunia @cakper 
Software Engineer @SensioLabsUK 
Symfony Certified Developer 
PHPers Silesia @PHPersPL
Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!
Software is complex
Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!
How to tackle it?
Domain-Driven Design is ! 
an approach to the 
development of complex 
software in which we: 
–Eric Evans
1. Focus on the core domain. 
–Eric Evans
2. Explore model in ! 
a creative collaboration of 
domain practitioners and 
software practitioners. 
–Eric Evans
3. Speak an ubiquitous 
language within an 
explicitly bounded context. 
–Eric Evans
When to use DDD?
Complex domain
Domain Experts
Iterative process
Object-Oriented Design
Strategic DDD
Strategy! 
! 
Stratos - army/resources! 
Ago - leading
Strategy! 
! 
! 
= What
Bounded Context
Bounded contexts of product 
❖ Catalogue! 
❖ Sales! 
❖Marketing! 
❖Warehouse
Ubiquitous language
Core Domain
Supporting Domain
Model-Driven Design
Continuous Integration
UI 
SERVICE 
UNIT
Refactoring Towards 
Deeper Insight
Tactical DDD
Tactics! 
! 
Taktike - the art of organising 
an army, a maneuver
Tactics! 
! 
! 
= How
Building Blocks
Layered architecture
USER INTERFACE 
APPLICATION 
DOMAIN 
INFRASTRUCTURE
. 
└── 
src 
└── 
Dcwroc 
├── 
Shopping 
├── 
Emejzon 
├── 
EmejzonBundle 
└── 
DoctrineAdapter
Entities
class 
Sale 
{ 
(…) 
private 
$id; 
! 
function 
__construct($name, 
DateTimeInterface 
$dueDate) 
{ 
$this-­‐>name 
= 
$name; 
$this-­‐>dueDate 
= 
$dueDate; 
} 
! 
public 
function 
getId() 
{ 
return 
$this-­‐>id; 
} 
}
class 
Sale 
{ 
(…) 
public 
function 
activate() 
{ 
if 
(true 
=== 
$this-­‐>active) 
{ 
throw 
new 
LogicException('Sale 
already 
activated!'); 
} 
! 
$this-­‐>active 
= 
true; 
} 
}
Value objects
class 
Email 
{ 
(…) 
public 
function 
__construct($email) 
{ 
if 
(!filter_var($email, 
FILTER_VALIDATE_EMAIL)) 
{ 
throw 
new 
InvalidArgumentException(); 
} 
! 
$this-­‐>email 
= 
$email; 
} 
! 
function 
asString() 
{ 
return 
$this-­‐>email; 
} 
}
Aggregates
class 
Order 
{(…) 
function 
__construct( 
Customer 
$customer, 
ProductList 
$productList 
){ 
$this-­‐>customer 
= 
$customer; 
$this-­‐>productList 
= 
$productList; 
$this-­‐>status 
= 
Status::open(); 
} 
! 
public 
function 
getTotal(); 
}
Repositories
interface 
OrderRepository 
{ 
public 
function 
save(Order 
$order); 
! 
public 
function 
remove(Order 
$order); 
public 
function 
findById($orderId); 
! 
public 
function 
findObsolete(); 
}
class 
DoctrineOrderRepository 
implements 
OrderRepository 
{} 
! 
class 
FileOrderRepository 
implements 
OrderRepository 
{} 
! 
class 
InMemoryOrderRepository 
implements 
OrderRepository 
{}
Factories
class 
CustomerFactory 
{ 
public 
function 
register(Email 
$email, 
Password 
$password) 
{ 
(...) 
! 
return 
$customer; 
} 
}
Services
interface 
Notifier 
{ 
public 
function 
send(Message 
$message); 
}
class 
EmailNotifier 
implements 
Notifier 
{ 
private 
$mailer; 
! 
function 
__construct(Swift_Mailer 
$mailer) 
{ 
$this-­‐>mailer 
= 
$mailer; 
} 
! 
public 
function 
send(Message 
$message) 
{ 
(…) 
} 
}
Domain Events
class 
ResetPassword 
{ 
function 
request(Email 
$email) 
{ 
$user 
= 
$this-­‐>userRepository-­‐>findOneByEmail($email); 
! 
if 
(!$user 
instanceof 
User) 
{ 
return 
$this-­‐>raise(new 
UserDoesNotExistEvent($email)); 
} 
! 
$request 
= 
Password::requestReset($user); 
$this-­‐>passwordResetRequestRepository-­‐>save($request); 
$this-­‐>raise(new 
RequestIssuedEvent($request)); 
} 
}
class 
ResetPassword 
{ 
function 
request(Email 
$email) 
{ 
$user 
= 
$this-­‐>userRepository-­‐>findOneByEmail($email); 
! 
if 
(!$user 
instanceof 
User) 
{ 
return 
$this-­‐>raise(new 
UserDoesNotExistEvent($email)); 
} 
! 
$request 
= 
Password::requestReset($user); 
$this-­‐>passwordResetRequestRepository-­‐>save($request); 
$this-­‐>raise(new 
RequestIssuedEvent($request)); 
} 
}
class 
ResetPassword 
{ 
function 
request(Email 
$email) 
{ 
$user 
= 
$this-­‐>userRepository-­‐>findOneByEmail($email); 
! 
if 
(!$user 
instanceof 
User) 
{ 
return 
$this-­‐>raise(new 
UserDoesNotExistEvent($email)); 
} 
! 
$request 
= 
Password::requestReset($user); 
$this-­‐>passwordResetRequestRepository-­‐>save($request); 
$this-­‐>raise(new 
RequestIssuedEvent($request)); 
} 
}
class 
ResetPassword 
{ 
function 
request(Email 
$email) 
{ 
$user 
= 
$this-­‐>userRepository-­‐>findOneByEmail($email); 
! 
if 
(!$user 
instanceof 
User) 
{ 
return 
$this-­‐>raise(new 
UserDoesNotExistEvent($email)); 
} 
! 
$request 
= 
Password::requestReset($user); 
$this-­‐>passwordResetRequestRepository-­‐>save($request); 
$this-­‐>raise(new 
RequestIssuedEvent($request)); 
} 
}
Modules
. 
└── 
Shopping 
└── 
Authentication 
├── 
InvalidPasswordResetRequest.php 
├── 
ResetPassword.php 
├── 
PasswordResetRequest.php 
└── 
PasswordResetRequestRepository.php
Supple Design
Make behaviour obvious
Intention revealing 
interfaces
Design for change
Create software other 
developers want 
to work with
Ignore persistance
Domain model is always 
in a valid state
Command Pattern
class 
ChangeEmailCommand 
{ 
public 
$email; 
public 
$customerId; 
}
class 
ChangeEmailCommandHandler 
{ 
private 
$customerRepository; 
! 
function 
__construct(CustomerRepository 
$customerRepository) 
{ 
$this-­‐>customerRepository 
= 
$customerRepository; 
} 
! 
public 
function 
handle(ChangeEmailCommand 
$command) 
{ 
$customer 
= 
$this-­‐>customerRepository 
-­‐>findById($command-­‐>customerId); 
$customer-­‐>changeEmail($command-­‐>email); 
} 
}
Specification Pattern
interface 
Specification 
{ 
public 
function 
isSatisfiedBy($object); 
}
class 
PayingCustomerSpecification 
implements 
Specification 
{ 
public 
function 
isSatisfiedBy($object) 
{ 
return 
$object 
instanceof 
Customer 
&& 
$object-­‐>getAmountSpent() 
> 
0.0; 
} 
}
class 
FreeDeliveryCalculator 
{ 
private 
$specification; 
! 
function 
__construct(Specification 
$specification) 
{ 
$this-­‐>specification 
= 
$specification; 
} 
! 
public 
function 
applyDiscount(Order 
$order) 
{ 
$customer 
= 
$this-­‐>$order-­‐>getCustomer(); 
if 
($this-­‐>specification-­‐>isSatisfiedBy($customer)) 
{ 
$order-­‐>deliverForFree(); 
} 
} 
}
class 
FreeDeliveryCalculator 
{ 
private 
$specification; 
! 
function 
__construct(Specification 
$specification) 
{ 
$this-­‐>specification 
= 
$specification; 
} 
! 
public 
function 
applyDiscount(Order 
$order) 
{ 
$customer 
= 
$this-­‐>$order-­‐>getCustomer(); 
if 
($this-­‐>specification-­‐>isSatisfiedBy($customer)) 
{ 
$order-­‐>deliverForFree(); 
} 
} 
}
Command-Query 
Responsibility 
Segregation
Commands
Use ORM to fetch/save 
aggregate roots
Queries
Use specialised queries 
and DTO’s to fetch 
presentation data
DDD Summary
Explore 
Domain Knowledge
With Domain Experts
By speaking 
Ubiquitous Language
Make use of 
Building Blocks
By applying 
Object-Oriented Design
Design for change
That’s the only constant!
“In order to create good 
software, you have to 
know what that software 
is all about.” 
–Eric Evans
Kacper Gunia 
Software Engineer 
Thanks! 
Symfony Certified Developer 
PHPers Silesia

More Related Content

What's hot (20)

PDF
Towards Functional Programming through Hexagonal Architecture
CodelyTV
 
PDF
PhpSpec 2.0 ilustrated by examples
Marcello Duarte
 
PDF
Dependency Injection Smells
Matthias Noback
 
PDF
TDD with PhpSpec
CiaranMcNulty
 
ODP
Drupal 8 entities & felds
Andy Postnikov
 
ODP
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
vvaswani
 
ODP
Symfony2, creare bundle e valore per il cliente
Leonardo Proietti
 
PDF
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Arc & Codementor
 
PDF
Meet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Ivan Chepurnyi
 
PDF
TDD with PhpSpec - Lone Star PHP 2016
CiaranMcNulty
 
KEY
PHPSpec BDD for PHP
Marcello Duarte
 
ZIP
Learning the basics of the Drupal API
Alexandru Badiu
 
PPTX
Crafting beautiful software
Jorn Oomen
 
PDF
Beyond MVC: from Model to Domain
Jeremy Cook
 
PDF
TDD with phpspec2
Anton Serdyuk
 
PDF
Dependency Injection
Fabien Potencier
 
PPT
Framework
Nguyen Linh
 
PDF
AngularJS with Slim PHP Micro Framework
Backand Cohen
 
PDF
What's new with PHP7
SWIFTotter Solutions
 
PDF
ACL in CodeIgniter
mirahman
 
Towards Functional Programming through Hexagonal Architecture
CodelyTV
 
PhpSpec 2.0 ilustrated by examples
Marcello Duarte
 
Dependency Injection Smells
Matthias Noback
 
TDD with PhpSpec
CiaranMcNulty
 
Drupal 8 entities & felds
Andy Postnikov
 
Creating REST Applications with the Slim Micro-Framework by Vikram Vaswani
vvaswani
 
Symfony2, creare bundle e valore per il cliente
Leonardo Proietti
 
Building Modern and Secure PHP Applications – Codementor Office Hours with Be...
Arc & Codementor
 
Meet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Ivan Chepurnyi
 
TDD with PhpSpec - Lone Star PHP 2016
CiaranMcNulty
 
PHPSpec BDD for PHP
Marcello Duarte
 
Learning the basics of the Drupal API
Alexandru Badiu
 
Crafting beautiful software
Jorn Oomen
 
Beyond MVC: from Model to Domain
Jeremy Cook
 
TDD with phpspec2
Anton Serdyuk
 
Dependency Injection
Fabien Potencier
 
Framework
Nguyen Linh
 
AngularJS with Slim PHP Micro Framework
Backand Cohen
 
What's new with PHP7
SWIFTotter Solutions
 
ACL in CodeIgniter
mirahman
 

Viewers also liked (15)

PPTX
Implementing DDD Concepts in PHP
Steve Rhoades
 
PDF
Clean architecture with ddd layering in php
Leonardo Proietti
 
PPTX
Drupal 8 Desacoplar la lógica de negocio del framework
Manuel López Torrent
 
PDF
Using HttpKernelInterface for Painless Integration
CiaranMcNulty
 
PPTX
Scalable Web Apps
Piotr Pelczar
 
PDF
Применение CQRS и EventSourcing в DDD-проекте
Igor Lubenets
 
ODP
Introduction to Domain-Driven Design
Yoan-Alexander Grigorov
 
ODP
Применение DDD подхода в Symfony 2 приложении
Антон Шабовта
 
PPTX
DDD Modeling Workshop
Dennis Traub
 
PPTX
DDD - модель вместо требований
SQALab
 
PPTX
How NOT to write in Node.js
Piotr Pelczar
 
PDF
DDD Workshop
Andrey Bibichev
 
PDF
A Visual Introduction to Event Sourcing and CQRS by Lorenzo Nicora
OpenCredo
 
PPT
Domain Driven Design (DDD)
Tom Kocjan
 
PDF
Developing event-driven microservices with event sourcing and CQRS (phillyete)
Chris Richardson
 
Implementing DDD Concepts in PHP
Steve Rhoades
 
Clean architecture with ddd layering in php
Leonardo Proietti
 
Drupal 8 Desacoplar la lógica de negocio del framework
Manuel López Torrent
 
Using HttpKernelInterface for Painless Integration
CiaranMcNulty
 
Scalable Web Apps
Piotr Pelczar
 
Применение CQRS и EventSourcing в DDD-проекте
Igor Lubenets
 
Introduction to Domain-Driven Design
Yoan-Alexander Grigorov
 
Применение DDD подхода в Symfony 2 приложении
Антон Шабовта
 
DDD Modeling Workshop
Dennis Traub
 
DDD - модель вместо требований
SQALab
 
How NOT to write in Node.js
Piotr Pelczar
 
DDD Workshop
Andrey Bibichev
 
A Visual Introduction to Event Sourcing and CQRS by Lorenzo Nicora
OpenCredo
 
Domain Driven Design (DDD)
Tom Kocjan
 
Developing event-driven microservices with event sourcing and CQRS (phillyete)
Chris Richardson
 
Ad

Similar to Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw! (20)

PPTX
An Introduction to Domain Driven Design in PHP
Chris Renner
 
PDF
Domain Driven Design
Pascal Larocque
 
PDF
ZG PHP - Specification
Robert Šorn
 
PDF
What is DDD and how could it help you
Luis Henrique Mulinari
 
PPTX
.NET Fest 2019. Halil Ibrahim Kalkan. Implementing Domain Driven Design
NETFest
 
PDF
Lithium: The Framework for People Who Hate Frameworks
Nate Abele
 
PDF
Baby steps to Domain-Driven Design
Žilvinas Kuusas
 
PDF
Unbreakable Domain Models PHPUK 2014 London
Mathias Verraes
 
PDF
How I started to love design patterns
Samuel ROZE
 
PPTX
Domain-Driven Design
Andriy Buday
 
PDF
Fighting legacy with hexagonal architecture and frameworkless php
Fabio Pellegrini
 
PDF
What is this DI and AOP stuff anyway...
Richard McIntyre
 
PDF
So S.O.L.I.D Fu - Designing Better Code
Neil Crookes
 
PDF
Domain Event - The Hidden Gem of DDD
Henrik Møller Rasmussen
 
PDF
WebCamp: Developer Day: DDD in PHP on example of Symfony - Олег Зинченко
GeeksLab Odessa
 
PDF
Beyond MVC: from Model to Domain
Jeremy Cook
 
PPTX
Domain Driven Design
Muhammad Ali
 
PDF
How I ended up contributing to Magento core
Alessandro Ronchi
 
PPTX
Schibsted Spain - Day 1 - DDD Course
Kevin Mas Ruiz
 
An Introduction to Domain Driven Design in PHP
Chris Renner
 
Domain Driven Design
Pascal Larocque
 
ZG PHP - Specification
Robert Šorn
 
What is DDD and how could it help you
Luis Henrique Mulinari
 
.NET Fest 2019. Halil Ibrahim Kalkan. Implementing Domain Driven Design
NETFest
 
Lithium: The Framework for People Who Hate Frameworks
Nate Abele
 
Baby steps to Domain-Driven Design
Žilvinas Kuusas
 
Unbreakable Domain Models PHPUK 2014 London
Mathias Verraes
 
How I started to love design patterns
Samuel ROZE
 
Domain-Driven Design
Andriy Buday
 
Fighting legacy with hexagonal architecture and frameworkless php
Fabio Pellegrini
 
What is this DI and AOP stuff anyway...
Richard McIntyre
 
So S.O.L.I.D Fu - Designing Better Code
Neil Crookes
 
Domain Event - The Hidden Gem of DDD
Henrik Møller Rasmussen
 
WebCamp: Developer Day: DDD in PHP on example of Symfony - Олег Зинченко
GeeksLab Odessa
 
Beyond MVC: from Model to Domain
Jeremy Cook
 
Domain Driven Design
Muhammad Ali
 
How I ended up contributing to Magento core
Alessandro Ronchi
 
Schibsted Spain - Day 1 - DDD Course
Kevin Mas Ruiz
 
Ad

More from Kacper Gunia (13)

PDF
How a large corporation used Domain-Driven Design to replace a loyalty system
Kacper Gunia
 
PDF
Rebuilding Legacy Apps with Domain-Driven Design - Lessons learned
Kacper Gunia
 
PDF
The top 10 things that any pro PHP developer should be doing
Kacper Gunia
 
PDF
Embrace Events and let CRUD die
Kacper Gunia
 
PDF
The IoC Hydra
Kacper Gunia
 
PDF
Forget about Index.php and build you applications around HTTP - PHPers Cracow
Kacper Gunia
 
PDF
OmniFocus - the #1 ‘Getting Things Done’ tool
Kacper Gunia
 
PDF
Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
Kacper Gunia
 
PDF
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Kacper Gunia
 
PDF
November Camp - Spec BDD with PHPSpec 2
Kacper Gunia
 
PDF
Dependency Injection in PHP
Kacper Gunia
 
PDF
Code Dojo
Kacper Gunia
 
PDF
SpecBDD in PHP
Kacper Gunia
 
How a large corporation used Domain-Driven Design to replace a loyalty system
Kacper Gunia
 
Rebuilding Legacy Apps with Domain-Driven Design - Lessons learned
Kacper Gunia
 
The top 10 things that any pro PHP developer should be doing
Kacper Gunia
 
Embrace Events and let CRUD die
Kacper Gunia
 
The IoC Hydra
Kacper Gunia
 
Forget about Index.php and build you applications around HTTP - PHPers Cracow
Kacper Gunia
 
OmniFocus - the #1 ‘Getting Things Done’ tool
Kacper Gunia
 
Scaling Symfony2 apps with RabbitMQ - Symfony UK Meetup
Kacper Gunia
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Kacper Gunia
 
November Camp - Spec BDD with PHPSpec 2
Kacper Gunia
 
Dependency Injection in PHP
Kacper Gunia
 
Code Dojo
Kacper Gunia
 
SpecBDD in PHP
Kacper Gunia
 

Recently uploaded (20)

PPTX
Mechanical Design of shell and tube heat exchangers as per ASME Sec VIII Divi...
shahveer210504
 
PPTX
Arduino Based Gas Leakage Detector Project
CircuitDigest
 
PPTX
Shinkawa Proposal to meet Vibration API670.pptx
AchmadBashori2
 
PPTX
GitOps_Repo_Structure for begeinner(Scaffolindg)
DanialHabibi2
 
PDF
Reasons for the succes of MENARD PRESSUREMETER.pdf
majdiamz
 
PDF
Basic_Concepts_in_Clinical_Biochemistry_2018كيمياء_عملي.pdf
AdelLoin
 
PDF
Unified_Cloud_Comm_Presentation anil singh ppt
anilsingh298751
 
PPTX
MobileComputingMANET2023 MobileComputingMANET2023.pptx
masterfake98765
 
PPTX
Depth First Search Algorithm in 🧠 DFS in Artificial Intelligence (AI)
rafeeqshaik212002
 
PPTX
Green Building & Energy Conservation ppt
Sagar Sarangi
 
PPTX
Evaluation and thermal analysis of shell and tube heat exchanger as per requi...
shahveer210504
 
PPTX
Damage of stability of a ship and how its change .pptx
ehamadulhaque
 
DOC
MRRS Strength and Durability of Concrete
CivilMythili
 
PDF
Pressure Measurement training for engineers and Technicians
AIESOLUTIONS
 
PDF
Ethics and Trustworthy AI in Healthcare – Governing Sensitive Data, Profiling...
AlqualsaDIResearchGr
 
PDF
GTU Civil Engineering All Semester Syllabus.pdf
Vimal Bhojani
 
PPTX
Worm gear strength and wear calculation as per standard VB Bhandari Databook.
shahveer210504
 
PDF
MAD Unit - 2 Activity and Fragment Management in Android (Diploma IT)
JappanMavani
 
PPTX
Thermal runway and thermal stability.pptx
godow93766
 
PDF
PORTFOLIO Golam Kibria Khan — architect with a passion for thoughtful design...
MasumKhan59
 
Mechanical Design of shell and tube heat exchangers as per ASME Sec VIII Divi...
shahveer210504
 
Arduino Based Gas Leakage Detector Project
CircuitDigest
 
Shinkawa Proposal to meet Vibration API670.pptx
AchmadBashori2
 
GitOps_Repo_Structure for begeinner(Scaffolindg)
DanialHabibi2
 
Reasons for the succes of MENARD PRESSUREMETER.pdf
majdiamz
 
Basic_Concepts_in_Clinical_Biochemistry_2018كيمياء_عملي.pdf
AdelLoin
 
Unified_Cloud_Comm_Presentation anil singh ppt
anilsingh298751
 
MobileComputingMANET2023 MobileComputingMANET2023.pptx
masterfake98765
 
Depth First Search Algorithm in 🧠 DFS in Artificial Intelligence (AI)
rafeeqshaik212002
 
Green Building & Energy Conservation ppt
Sagar Sarangi
 
Evaluation and thermal analysis of shell and tube heat exchanger as per requi...
shahveer210504
 
Damage of stability of a ship and how its change .pptx
ehamadulhaque
 
MRRS Strength and Durability of Concrete
CivilMythili
 
Pressure Measurement training for engineers and Technicians
AIESOLUTIONS
 
Ethics and Trustworthy AI in Healthcare – Governing Sensitive Data, Profiling...
AlqualsaDIResearchGr
 
GTU Civil Engineering All Semester Syllabus.pdf
Vimal Bhojani
 
Worm gear strength and wear calculation as per standard VB Bhandari Databook.
shahveer210504
 
MAD Unit - 2 Activity and Fragment Management in Android (Diploma IT)
JappanMavani
 
Thermal runway and thermal stability.pptx
godow93766
 
PORTFOLIO Golam Kibria Khan — architect with a passion for thoughtful design...
MasumKhan59
 

Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!