SlideShare une entreprise Scribd logo
1  sur  68
Hello!Hello!
Who am I?Who am I?
Yoan-Alexander GrigorovYoan-Alexander Grigorov
Software EngineerSoftware Engineer
Design Patterns adventurerDesign Patterns adventurer
GNU/Linux userGNU/Linux user
What is a Domain Model?What is a Domain Model?
Business Domain ModelBusiness Domain Model
<?php<?php
// ...// ...
$insurance$insurance->->addCoveredPerson(addCoveredPerson(
newnew CoveredPersonCoveredPerson(('Yoan-Alexander''Yoan-Alexander',, newnew AgeAge((2323))))
););
// ...// ...
// ...// ...
ifif (($ticket$ticket->->isExpired(isExpired(newnew DateTimeDateTime(('now''now'))) {))) {
// alert user that ticket has expired// alert user that ticket has expired
}}
Ubiquitous languageUbiquitous language
Application ModelApplication Model
// The connection URL// The connection URL
StringString urlurl == "https://ajax.googleapis.com/ajax/""https://ajax.googleapis.com/ajax/" ++
"services/search/web?v=1.0&q={query}""services/search/web?v=1.0&q={query}";;
// Create a new RestTemplate instance// Create a new RestTemplate instance
RestTemplateRestTemplate restTemplaterestTemplate == newnew RestTemplateRestTemplate();();
// Add the String message converter// Add the String message converter
restTemplaterestTemplate..getMessageConverters()getMessageConverters()..add(add(newnew
StringHttpMessageConverterStringHttpMessageConverter());());
// Make the HTTP GET request, marshaling the response to a String// Make the HTTP GET request, marshaling the response to a String
StringString resultresult == restTemplaterestTemplate..getForObject(url,getForObject(url, StringString..class,class,
"Android""Android"););
MVCMVC
MVC starts with the word “Model”MVC starts with the word “Model”
●
Model != ClassModel != Class
●
A model would express logic implementationA model would express logic implementation
●
A model is not always required to be CRUDA model is not always required to be CRUD
implementationimplementation
Widely used bad practicesWidely used bad practices
●
One controller – one “model”One controller – one “model”
●
Widely inheriting a common abstract class,Widely inheriting a common abstract class,
which contains helper methodswhich contains helper methods
●
Logic in view scriptsLogic in view scripts
●
Messy controllersMessy controllers
Why we should never keep anyWhy we should never keep any
logic in controllers?logic in controllers?
Compulsive hoardingCompulsive hoarding
Domain-Driven Design?Domain-Driven Design?
What Domain-Driven Design CAN'T do?What Domain-Driven Design CAN'T do?
●
Stop a huge asteroid heading to earthStop a huge asteroid heading to earth
●
Cure plagueCure plague
●
Can't beat node.js (because node.js is the bestCan't beat node.js (because node.js is the best
thing happened to the universe)thing happened to the universe)
●
Answer the question “Why are we here?!”Answer the question “Why are we here?!”
●
Bring dinosaurs back to lifeBring dinosaurs back to life
●
Prove the events from the Holy BibleProve the events from the Holy Bible
With what can Domain-Driven DesignWith what can Domain-Driven Design
help you?help you?
●
Escape from the code messEscape from the code mess
●
Provide loosely coupled classes to yourProvide loosely coupled classes to your
projectproject
●
Help you in decisions about data structuringHelp you in decisions about data structuring
●
Give you some tips about where to keep stateGive you some tips about where to keep state
and behaviorand behavior
Building BlocksBuilding Blocks
Value ObjectsValue Objects
Example:Example:
Saving IP address with a validationSaving IP address with a validation
<?php<?php
// ...// ...
public functionpublic function insertinsert((stringstring $ipAddress)$ipAddress)
{{
$ipAddressPattern$ipAddressPattern == '/'/^^(?:(?:2[0-4]...........-5]))?(?:(?:2[0-4]...........-5]))?$$/'/';;
ifif ((!!preg_matchpreg_match($ipAddressPattern, $ipAddress)) {($ipAddressPattern, $ipAddress)) {
throwthrow newnew WrongIpAddressExceptionWrongIpAddressException();();
}}
$this$this->->dbdb->->insert([insert([
'ipAddress''ipAddress' =>=> $ipAddress$ipAddress
]);]);
}}
// ...// ...
<?php<?php
// ...// ...
private functionprivate function isIpAddressValidisIpAddressValid((stringstring $ipAddress)$ipAddress)
{{
$ipAddressPattern$ipAddressPattern == '/'/^^(?:(?:2[0-4]...........-5]))?(?:(?:2[0-4]...........-5]))?$$/'/';;
ifif ((!!preg_matchpreg_match($ipAddressPattern, $ipAddress)) {($ipAddressPattern, $ipAddress)) {
returnreturn falsefalse;;
}}
returnreturn truetrue;;
}}
public functionpublic function insertinsert((stringstring $ipAddress)$ipAddress)
{{
ifif ((!!$this$this->->isIpAddressValid($ipAddress)) {isIpAddressValid($ipAddress)) {
throwthrow newnew WrongIpAddressExceptionWrongIpAddressException();();
}}
$this$this->->dbdb->->insert([insert([
'ipAddress''ipAddress' =>=> $ipAddress$ipAddress
]);]);
}}
// ...// ...
There, I fixed it!There, I fixed it!
Can we do it better?Can we do it better?
<?php<?php
classclass IpAddressIpAddress
{{
constconst stringstring VALIDATION_REGEXVALIDATION_REGEX == '/'/^^(?:(?:2[0-4]........-5]))?(?:(?:2[0-4]........-5]))?$$/'/';;
privateprivate stringstring $ipAddress;$ipAddress;
public functionpublic function __construct__construct((stringstring $ipAddress)$ipAddress)
{{
ifif ((!!preg_matchpreg_match((self::self::VALIDATION_REGEXVALIDATION_REGEX, $ipAddress)) {, $ipAddress)) {
throwthrow newnew WrongIpAddressExceptionWrongIpAddressException();();
}}
$this$this->->ipAddressipAddress == $ipAddress;$ipAddress;
}}
public functionpublic function toStringtoString()()
{{
returnreturn $this$this->->ipAddress;ipAddress;
}}
}}
<?php<?php
// ...// ...
public functionpublic function insertinsert((IpAddressIpAddress $ipAddress)$ipAddress)
{{
$this$this->->dbdb->->insert([insert([
'ipAddress''ipAddress' =>=> $ipAddress$ipAddress->->toString()toString()
]);]);
}}
// ...// ...
RememberRemember
●
Value ObjectsValue Objects shouldshould be immutablebe immutable
●
Two value objects with the same attributeTwo value objects with the same attribute
values are considered the samevalues are considered the same
Examples for embedded valueExamples for embedded value
objectsobjects
●
DateTime in PHPDateTime in PHP
●
java.lang.Integer in Java (and a lot more)java.lang.Integer in Java (and a lot more)
●
Number, String, Date in JavaScriptNumber, String, Date in JavaScript
EntitiesEntities
Object-Relational Mappers?Object-Relational Mappers?
What is an Entity?What is an Entity?
●
Objects, which could be distinguished byObjects, which could be distinguished by
some identifier (Primary Key?)some identifier (Primary Key?)
●
Entity objects are mutable (unlike valueEntity objects are mutable (unlike value
objects)objects)
●
Two entities with the same attribute values areTwo entities with the same attribute values are
not the same thing (unlike value objects)not the same thing (unlike value objects)
Yoan AlexanderYoan Alexander
!=!=
Example entitiesExample entities
RepositoriesRepositories
●
Repositories support entities lifecycleRepositories support entities lifecycle
●
From repositories you can fetch entitiesFrom repositories you can fetch entities
●
You can save entities to a data-source using aYou can save entities to a data-source using a
repository objectrepository object
Can we place a “seriousCan we place a “serious”” businessbusiness
logic inside entity classes?logic inside entity classes?
NO.NO.
●
Structure of entitiesStructure of entities
●
There is one main entity calledThere is one main entity called Aggregate RootAggregate Root
●
In the Orders aggregate, a User is part of an OrderIn the Orders aggregate, a User is part of an Order
●
In other scenario we can have another aggregate in which User isIn other scenario we can have another aggregate in which User is
the main entity (aggregate root)the main entity (aggregate root)
●
Each aggregate has it's corresponding repositoryEach aggregate has it's corresponding repository
AggregateAggregate
Repositories and aggregatesRepositories and aggregates
●
When we want to fetch something from theWhen we want to fetch something from the
OrdersRepository, we get the whole aggregateOrdersRepository, we get the whole aggregate
(Order + User)(Order + User)
What about the logic-leaders?What about the logic-leaders?
ServicesServices
Service Layer != Web ServicesService Layer != Web Services
Service classesService classes
●
They manage tasks from a higher (moreThey manage tasks from a higher (more
general) levelgeneral) level
●
They should do exactly what they name tellsThey should do exactly what they name tells
usus
●
Single Responsibility PrincipleSingle Responsibility Principle
●
They need to be SIMPLE!They need to be SIMPLE!
<?php<?php
//... Users registration controller ....//... Users registration controller ....
public functionpublic function signUpActionsignUpAction()()
{{
// ...// ...
$userCreator$userCreator == newnew UserCreatorUserCreator();();
$userCreator$userCreator->->registerNewUser(registerNewUser(
$email, $password, $fullName, $phone$email, $password, $fullName, $phone
););
// ...// ...
}}
<?php<?php
classclass UserCreatorUserCreator {{
privateprivate $usersRepository;$usersRepository;
privateprivate $emailNotifier;$emailNotifier;
public functionpublic function __construct__construct((
UsersRepositoryUsersRepository $usersRepository,$usersRepository,
NewAccountNotifierNewAccountNotifier $emailNotifier)$emailNotifier)
{{
$this$this->->usersRepositoryusersRepository == $usersRepository;$usersRepository;
$this$this->->emailNotifieremailNotifier == $emailNotifier;$emailNotifier;
}}
public functionpublic function registerNewUserregisterNewUser((
EmailEmail $email,$email, PasswordPassword $password,$password,
stringstring $fullName,$fullName, PhoneNumberPhoneNumber $phone$phone == nullnull))
{{
$user$user == newnew UserUser($email, $password, $fullName, $phone);($email, $password, $fullName, $phone);
$this$this->->usersRepositoryusersRepository->->insert($user);insert($user);
$this$this->->emailNotifieremailNotifier->->sendNotification($user);sendNotification($user);
}}
}}
<?php<?php
// ...// ...
public functionpublic function registerNewUserregisterNewUser((
EmailEmail $email,$email, PasswordPassword $password,$password,
stringstring $fullName,$fullName, PhoneNumberPhoneNumber $phone$phone == nullnull))
{{
$user$user == newnew UserUser($email, $password, $fullName, $phone);($email, $password, $fullName, $phone);
$this$this->->usersRepositoryusersRepository->->insert($user);insert($user);
$this$this->->eventManagereventManager->->trigger(trigger('NewAccountCreated''NewAccountCreated', $user);, $user);
}}
<?php<?php
// ... Confirguration// ... Confirguration
$eventManager$eventManager->->on(on('NewAccountCreated''NewAccountCreated',, functionfunction ((UserUser $user) {$user) {
$emailNotifier$emailNotifier == newnew NewAccountNotifierNewAccountNotifier();();
$emailNotifier$emailNotifier->->sendNotification($user);sendNotification($user);
});});
Some good advicesSome good advices
●
Do not put “Entity” in your entities class namesDo not put “Entity” in your entities class names
●
Avoid placing “Manager” or “Service” in theAvoid placing “Manager” or “Service” in the
class names of your service layer classesclass names of your service layer classes
●
One service class should not contain moreOne service class should not contain more
then 3 dependenciesthen 3 dependencies
We want more examples!We want more examples!
We have this desktop application which weWe have this desktop application which we
were using for our customers. We need to bringwere using for our customers. We need to bring
all of the existing user profiles from there to theall of the existing user profiles from there to the
web systemweb system
We are braking the singleWe are braking the single
responsibility principle... badly!responsibility principle... badly!
The class is named “UserCreator”The class is named “UserCreator”
…… notnot
UserCreatorAndImporterFromSomewhereElUserCreatorAndImporterFromSomewhereEl
sese
Another example?Another example?
We want our customers to be able toWe want our customers to be able to
use Facebook for their registrationsuse Facebook for their registrations
Grouping and packagingGrouping and packaging
●
NEVER group by pattern (e.g. packageNEVER group by pattern (e.g. package
Entities or Repositories)Entities or Repositories)
●
Group by meaningGroup by meaning
Get ready for endless refactoring!Get ready for endless refactoring!
Admit your mistakes before yourself!Admit your mistakes before yourself!
More on this topicMore on this topic
More on this topicMore on this topic
Thanks for listening!Thanks for listening!
Contacts:Contacts:
●
joan.grigorov@gmail.comjoan.grigorov@gmail.com
●
@YoanDev@YoanDev
●
http://linkedin.com/in/yoangrigorovhttp://linkedin.com/in/yoangrigorov

Contenu connexe

Tendances

The art of readable code (ch1~ch4)
The art of readable code (ch1~ch4)The art of readable code (ch1~ch4)
The art of readable code (ch1~ch4)Ki Sung Bae
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency InjectionRifat Nabi
 
The Art Of Readable Code
The Art Of Readable CodeThe Art Of Readable Code
The Art Of Readable CodeBaidu, Inc.
 
Building High Performance Web Applications and Sites
Building High Performance Web Applications and SitesBuilding High Performance Web Applications and Sites
Building High Performance Web Applications and Sitesgoodfriday
 
Models and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsModels and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsRoss Tuck
 
RubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY SyntaxRubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY SyntaxDr Nic Williams
 
Realm or: How I learned to stop worrying and love my app database
Realm or: How I learned to stop worrying and love my app databaseRealm or: How I learned to stop worrying and love my app database
Realm or: How I learned to stop worrying and love my app databaseSergi Martínez
 
Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixturesBill Chang
 
PHP Data Objects
PHP Data ObjectsPHP Data Objects
PHP Data ObjectsWez Furlong
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownpartsBastian Feder
 
Система рендеринга в Magento
Система рендеринга в MagentoСистема рендеринга в Magento
Система рендеринга в MagentoMagecom Ukraine
 
Typescript - why it's awesome
Typescript - why it's awesomeTypescript - why it's awesome
Typescript - why it's awesomePiotr Miazga
 
groovy databases
groovy databasesgroovy databases
groovy databasesPaul King
 
Intro To Moose
Intro To MooseIntro To Moose
Intro To MoosecPanel
 
Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Fabien Potencier
 
OSDC.fr 2012 :: Cascalog : progammation logique pour Hadoop
OSDC.fr 2012 :: Cascalog : progammation logique pour HadoopOSDC.fr 2012 :: Cascalog : progammation logique pour Hadoop
OSDC.fr 2012 :: Cascalog : progammation logique pour HadoopPublicis Sapient Engineering
 
Working Effectively With Legacy Tdiary Code Using Cucumber And Rspec
Working Effectively With Legacy Tdiary Code Using Cucumber And RspecWorking Effectively With Legacy Tdiary Code Using Cucumber And Rspec
Working Effectively With Legacy Tdiary Code Using Cucumber And RspecShintaro Kakutani
 

Tendances (20)

The art of readable code (ch1~ch4)
The art of readable code (ch1~ch4)The art of readable code (ch1~ch4)
The art of readable code (ch1~ch4)
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
The Art Of Readable Code
The Art Of Readable CodeThe Art Of Readable Code
The Art Of Readable Code
 
Building High Performance Web Applications and Sites
Building High Performance Web Applications and SitesBuilding High Performance Web Applications and Sites
Building High Performance Web Applications and Sites
 
Models and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and HobgoblinsModels and Service Layers, Hemoglobin and Hobgoblins
Models and Service Layers, Hemoglobin and Hobgoblins
 
RubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY SyntaxRubyEnRails2007 - Dr Nic Williams - DIY Syntax
RubyEnRails2007 - Dr Nic Williams - DIY Syntax
 
Terrific Frontends
Terrific FrontendsTerrific Frontends
Terrific Frontends
 
Your Entity, Your Code
Your Entity, Your CodeYour Entity, Your Code
Your Entity, Your Code
 
Realm or: How I learned to stop worrying and love my app database
Realm or: How I learned to stop worrying and love my app databaseRealm or: How I learned to stop worrying and love my app database
Realm or: How I learned to stop worrying and love my app database
 
Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixtures
 
PHP Data Objects
PHP Data ObjectsPHP Data Objects
PHP Data Objects
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
Система рендеринга в Magento
Система рендеринга в MagentoСистема рендеринга в Magento
Система рендеринга в Magento
 
Typescript - why it's awesome
Typescript - why it's awesomeTypescript - why it's awesome
Typescript - why it's awesome
 
groovy databases
groovy databasesgroovy databases
groovy databases
 
Intro To Moose
Intro To MooseIntro To Moose
Intro To Moose
 
Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3
 
OSDC.fr 2012 :: Cascalog : progammation logique pour Hadoop
OSDC.fr 2012 :: Cascalog : progammation logique pour HadoopOSDC.fr 2012 :: Cascalog : progammation logique pour Hadoop
OSDC.fr 2012 :: Cascalog : progammation logique pour Hadoop
 
Hooks WCSD12
Hooks WCSD12Hooks WCSD12
Hooks WCSD12
 
Working Effectively With Legacy Tdiary Code Using Cucumber And Rspec
Working Effectively With Legacy Tdiary Code Using Cucumber And RspecWorking Effectively With Legacy Tdiary Code Using Cucumber And Rspec
Working Effectively With Legacy Tdiary Code Using Cucumber And Rspec
 

En vedette

Implementing DDD Concepts in PHP
Implementing DDD Concepts in PHPImplementing DDD Concepts in PHP
Implementing DDD Concepts in PHPSteve Rhoades
 
Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!
Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!
Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!Kacper Gunia
 
DDD - модель вместо требований
DDD - модель вместо требованийDDD - модель вместо требований
DDD - модель вместо требованийSQALab
 
DDD Modeling Workshop
DDD Modeling WorkshopDDD Modeling Workshop
DDD Modeling WorkshopDennis Traub
 
Domain Driven Design (DDD)
Domain Driven Design (DDD)Domain Driven Design (DDD)
Domain Driven Design (DDD)Tom Kocjan
 
A Practical Guide to Domain Driven Design: Presentation Slides
A Practical Guide to Domain Driven Design: Presentation SlidesA Practical Guide to Domain Driven Design: Presentation Slides
A Practical Guide to Domain Driven Design: Presentation Slidesthinkddd
 
Domain Driven Design using Laravel
Domain Driven Design using LaravelDomain Driven Design using Laravel
Domain Driven Design using Laravelwajrcs
 

En vedette (11)

DDD Workshop
DDD WorkshopDDD Workshop
DDD Workshop
 
Implementing DDD Concepts in PHP
Implementing DDD Concepts in PHPImplementing DDD Concepts in PHP
Implementing DDD Concepts in PHP
 
A brief look inside UML
A brief look inside UMLA brief look inside UML
A brief look inside UML
 
SOLID design
SOLID designSOLID design
SOLID design
 
WebSockets with PHP: Mission impossible
WebSockets with PHP: Mission impossibleWebSockets with PHP: Mission impossible
WebSockets with PHP: Mission impossible
 
Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!
Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!
Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!
 
DDD - модель вместо требований
DDD - модель вместо требованийDDD - модель вместо требований
DDD - модель вместо требований
 
DDD Modeling Workshop
DDD Modeling WorkshopDDD Modeling Workshop
DDD Modeling Workshop
 
Domain Driven Design (DDD)
Domain Driven Design (DDD)Domain Driven Design (DDD)
Domain Driven Design (DDD)
 
A Practical Guide to Domain Driven Design: Presentation Slides
A Practical Guide to Domain Driven Design: Presentation SlidesA Practical Guide to Domain Driven Design: Presentation Slides
A Practical Guide to Domain Driven Design: Presentation Slides
 
Domain Driven Design using Laravel
Domain Driven Design using LaravelDomain Driven Design using Laravel
Domain Driven Design using Laravel
 

Similaire à Introduction to Domain-Driven Design

Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best PracticesYekmer Simsek
 
EP2016 - Moving Away From Nodejs To A Pure Python Solution For Assets
EP2016 - Moving Away From Nodejs To A Pure Python Solution For AssetsEP2016 - Moving Away From Nodejs To A Pure Python Solution For Assets
EP2016 - Moving Away From Nodejs To A Pure Python Solution For AssetsAlessandro Molina
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyDavid Padbury
 
Questioning the status quo
Questioning the status quoQuestioning the status quo
Questioning the status quoIvano Pagano
 
DDD on example of Symfony (Webcamp Odessa 2014)
DDD on example of Symfony (Webcamp Odessa 2014)DDD on example of Symfony (Webcamp Odessa 2014)
DDD on example of Symfony (Webcamp Odessa 2014)Oleg Zinchenko
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
JavaScript, React Native and Performance at react-europe 2016
JavaScript, React Native and Performance at react-europe 2016JavaScript, React Native and Performance at react-europe 2016
JavaScript, React Native and Performance at react-europe 2016Tadeu Zagallo
 
DDD on example of Symfony (SfCampUA14)
DDD on example of Symfony (SfCampUA14)DDD on example of Symfony (SfCampUA14)
DDD on example of Symfony (SfCampUA14)Oleg Zinchenko
 
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)James Titcumb
 
So S.O.L.I.D Fu - Designing Better Code
So S.O.L.I.D Fu - Designing Better CodeSo S.O.L.I.D Fu - Designing Better Code
So S.O.L.I.D Fu - Designing Better CodeNeil Crookes
 
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)James Titcumb
 
From Android NDK To AOSP
From Android NDK To AOSPFrom Android NDK To AOSP
From Android NDK To AOSPMin-Yih Hsu
 
Bubbles & Trees with jQuery
Bubbles & Trees with jQueryBubbles & Trees with jQuery
Bubbles & Trees with jQueryBastian Feder
 
From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)Jose Manuel Pereira Garcia
 

Similaire à Introduction to Domain-Driven Design (20)

Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best Practices
 
Having Fun with Play
Having Fun with PlayHaving Fun with Play
Having Fun with Play
 
Spl Not A Bridge Too Far phpNW09
Spl Not A Bridge Too Far phpNW09Spl Not A Bridge Too Far phpNW09
Spl Not A Bridge Too Far phpNW09
 
EP2016 - Moving Away From Nodejs To A Pure Python Solution For Assets
EP2016 - Moving Away From Nodejs To A Pure Python Solution For AssetsEP2016 - Moving Away From Nodejs To A Pure Python Solution For Assets
EP2016 - Moving Away From Nodejs To A Pure Python Solution For Assets
 
Development Principles & Philosophy
Development Principles & PhilosophyDevelopment Principles & Philosophy
Development Principles & Philosophy
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight Guy
 
Make it SOLID!
Make it SOLID!Make it SOLID!
Make it SOLID!
 
Questioning the status quo
Questioning the status quoQuestioning the status quo
Questioning the status quo
 
DDD on example of Symfony (Webcamp Odessa 2014)
DDD on example of Symfony (Webcamp Odessa 2014)DDD on example of Symfony (Webcamp Odessa 2014)
DDD on example of Symfony (Webcamp Odessa 2014)
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
JavaScript, React Native and Performance at react-europe 2016
JavaScript, React Native and Performance at react-europe 2016JavaScript, React Native and Performance at react-europe 2016
JavaScript, React Native and Performance at react-europe 2016
 
DDD on example of Symfony (SfCampUA14)
DDD on example of Symfony (SfCampUA14)DDD on example of Symfony (SfCampUA14)
DDD on example of Symfony (SfCampUA14)
 
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
 
So S.O.L.I.D Fu - Designing Better Code
So S.O.L.I.D Fu - Designing Better CodeSo S.O.L.I.D Fu - Designing Better Code
So S.O.L.I.D Fu - Designing Better Code
 
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
 
From Android NDK To AOSP
From Android NDK To AOSPFrom Android NDK To AOSP
From Android NDK To AOSP
 
Bubbles & Trees with jQuery
Bubbles & Trees with jQueryBubbles & Trees with jQuery
Bubbles & Trees with jQuery
 
Fact, Fiction, and FP
Fact, Fiction, and FPFact, Fiction, and FP
Fact, Fiction, and FP
 
Gwt.create
Gwt.createGwt.create
Gwt.create
 
From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)
 

Dernier

Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptkotipi9215
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Intelisync
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number SystemsJheuzeDellosa
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...aditisharan08
 

Dernier (20)

Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.ppt
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number Systems
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...
 

Introduction to Domain-Driven Design

  • 2. Who am I?Who am I? Yoan-Alexander GrigorovYoan-Alexander Grigorov Software EngineerSoftware Engineer Design Patterns adventurerDesign Patterns adventurer GNU/Linux userGNU/Linux user
  • 3. What is a Domain Model?What is a Domain Model?
  • 4.
  • 5. Business Domain ModelBusiness Domain Model <?php<?php // ...// ... $insurance$insurance->->addCoveredPerson(addCoveredPerson( newnew CoveredPersonCoveredPerson(('Yoan-Alexander''Yoan-Alexander',, newnew AgeAge((2323)))) );); // ...// ... // ...// ... ifif (($ticket$ticket->->isExpired(isExpired(newnew DateTimeDateTime(('now''now'))) {))) { // alert user that ticket has expired// alert user that ticket has expired }}
  • 7. Application ModelApplication Model // The connection URL// The connection URL StringString urlurl == "https://ajax.googleapis.com/ajax/""https://ajax.googleapis.com/ajax/" ++ "services/search/web?v=1.0&q={query}""services/search/web?v=1.0&q={query}";; // Create a new RestTemplate instance// Create a new RestTemplate instance RestTemplateRestTemplate restTemplaterestTemplate == newnew RestTemplateRestTemplate();(); // Add the String message converter// Add the String message converter restTemplaterestTemplate..getMessageConverters()getMessageConverters()..add(add(newnew StringHttpMessageConverterStringHttpMessageConverter());()); // Make the HTTP GET request, marshaling the response to a String// Make the HTTP GET request, marshaling the response to a String StringString resultresult == restTemplaterestTemplate..getForObject(url,getForObject(url, StringString..class,class, "Android""Android"););
  • 8.
  • 10.
  • 11. MVC starts with the word “Model”MVC starts with the word “Model” ● Model != ClassModel != Class ● A model would express logic implementationA model would express logic implementation ● A model is not always required to be CRUDA model is not always required to be CRUD implementationimplementation
  • 12. Widely used bad practicesWidely used bad practices ● One controller – one “model”One controller – one “model” ● Widely inheriting a common abstract class,Widely inheriting a common abstract class, which contains helper methodswhich contains helper methods ● Logic in view scriptsLogic in view scripts ● Messy controllersMessy controllers
  • 13. Why we should never keep anyWhy we should never keep any logic in controllers?logic in controllers?
  • 14.
  • 17. What Domain-Driven Design CAN'T do?What Domain-Driven Design CAN'T do? ● Stop a huge asteroid heading to earthStop a huge asteroid heading to earth ● Cure plagueCure plague ● Can't beat node.js (because node.js is the bestCan't beat node.js (because node.js is the best thing happened to the universe)thing happened to the universe) ● Answer the question “Why are we here?!”Answer the question “Why are we here?!” ● Bring dinosaurs back to lifeBring dinosaurs back to life ● Prove the events from the Holy BibleProve the events from the Holy Bible
  • 18. With what can Domain-Driven DesignWith what can Domain-Driven Design help you?help you? ● Escape from the code messEscape from the code mess ● Provide loosely coupled classes to yourProvide loosely coupled classes to your projectproject ● Help you in decisions about data structuringHelp you in decisions about data structuring ● Give you some tips about where to keep stateGive you some tips about where to keep state and behaviorand behavior
  • 21. Example:Example: Saving IP address with a validationSaving IP address with a validation
  • 22. <?php<?php // ...// ... public functionpublic function insertinsert((stringstring $ipAddress)$ipAddress) {{ $ipAddressPattern$ipAddressPattern == '/'/^^(?:(?:2[0-4]...........-5]))?(?:(?:2[0-4]...........-5]))?$$/'/';; ifif ((!!preg_matchpreg_match($ipAddressPattern, $ipAddress)) {($ipAddressPattern, $ipAddress)) { throwthrow newnew WrongIpAddressExceptionWrongIpAddressException();(); }} $this$this->->dbdb->->insert([insert([ 'ipAddress''ipAddress' =>=> $ipAddress$ipAddress ]);]); }} // ...// ...
  • 23. <?php<?php // ...// ... private functionprivate function isIpAddressValidisIpAddressValid((stringstring $ipAddress)$ipAddress) {{ $ipAddressPattern$ipAddressPattern == '/'/^^(?:(?:2[0-4]...........-5]))?(?:(?:2[0-4]...........-5]))?$$/'/';; ifif ((!!preg_matchpreg_match($ipAddressPattern, $ipAddress)) {($ipAddressPattern, $ipAddress)) { returnreturn falsefalse;; }} returnreturn truetrue;; }} public functionpublic function insertinsert((stringstring $ipAddress)$ipAddress) {{ ifif ((!!$this$this->->isIpAddressValid($ipAddress)) {isIpAddressValid($ipAddress)) { throwthrow newnew WrongIpAddressExceptionWrongIpAddressException();(); }} $this$this->->dbdb->->insert([insert([ 'ipAddress''ipAddress' =>=> $ipAddress$ipAddress ]);]); }} // ...// ...
  • 24. There, I fixed it!There, I fixed it!
  • 25. Can we do it better?Can we do it better?
  • 26. <?php<?php classclass IpAddressIpAddress {{ constconst stringstring VALIDATION_REGEXVALIDATION_REGEX == '/'/^^(?:(?:2[0-4]........-5]))?(?:(?:2[0-4]........-5]))?$$/'/';; privateprivate stringstring $ipAddress;$ipAddress; public functionpublic function __construct__construct((stringstring $ipAddress)$ipAddress) {{ ifif ((!!preg_matchpreg_match((self::self::VALIDATION_REGEXVALIDATION_REGEX, $ipAddress)) {, $ipAddress)) { throwthrow newnew WrongIpAddressExceptionWrongIpAddressException();(); }} $this$this->->ipAddressipAddress == $ipAddress;$ipAddress; }} public functionpublic function toStringtoString()() {{ returnreturn $this$this->->ipAddress;ipAddress; }} }}
  • 27. <?php<?php // ...// ... public functionpublic function insertinsert((IpAddressIpAddress $ipAddress)$ipAddress) {{ $this$this->->dbdb->->insert([insert([ 'ipAddress''ipAddress' =>=> $ipAddress$ipAddress->->toString()toString() ]);]); }} // ...// ...
  • 28.
  • 29. RememberRemember ● Value ObjectsValue Objects shouldshould be immutablebe immutable ● Two value objects with the same attributeTwo value objects with the same attribute values are considered the samevalues are considered the same
  • 30. Examples for embedded valueExamples for embedded value objectsobjects ● DateTime in PHPDateTime in PHP ● java.lang.Integer in Java (and a lot more)java.lang.Integer in Java (and a lot more) ● Number, String, Date in JavaScriptNumber, String, Date in JavaScript
  • 33. What is an Entity?What is an Entity? ● Objects, which could be distinguished byObjects, which could be distinguished by some identifier (Primary Key?)some identifier (Primary Key?) ● Entity objects are mutable (unlike valueEntity objects are mutable (unlike value objects)objects) ● Two entities with the same attribute values areTwo entities with the same attribute values are not the same thing (unlike value objects)not the same thing (unlike value objects)
  • 36. RepositoriesRepositories ● Repositories support entities lifecycleRepositories support entities lifecycle ● From repositories you can fetch entitiesFrom repositories you can fetch entities ● You can save entities to a data-source using aYou can save entities to a data-source using a repository objectrepository object
  • 37. Can we place a “seriousCan we place a “serious”” businessbusiness logic inside entity classes?logic inside entity classes?
  • 39. ● Structure of entitiesStructure of entities ● There is one main entity calledThere is one main entity called Aggregate RootAggregate Root ● In the Orders aggregate, a User is part of an OrderIn the Orders aggregate, a User is part of an Order ● In other scenario we can have another aggregate in which User isIn other scenario we can have another aggregate in which User is the main entity (aggregate root)the main entity (aggregate root) ● Each aggregate has it's corresponding repositoryEach aggregate has it's corresponding repository AggregateAggregate
  • 40.
  • 41. Repositories and aggregatesRepositories and aggregates ● When we want to fetch something from theWhen we want to fetch something from the OrdersRepository, we get the whole aggregateOrdersRepository, we get the whole aggregate (Order + User)(Order + User)
  • 42. What about the logic-leaders?What about the logic-leaders?
  • 44. Service Layer != Web ServicesService Layer != Web Services
  • 45. Service classesService classes ● They manage tasks from a higher (moreThey manage tasks from a higher (more general) levelgeneral) level ● They should do exactly what they name tellsThey should do exactly what they name tells usus ● Single Responsibility PrincipleSingle Responsibility Principle ● They need to be SIMPLE!They need to be SIMPLE!
  • 46. <?php<?php //... Users registration controller ....//... Users registration controller .... public functionpublic function signUpActionsignUpAction()() {{ // ...// ... $userCreator$userCreator == newnew UserCreatorUserCreator();(); $userCreator$userCreator->->registerNewUser(registerNewUser( $email, $password, $fullName, $phone$email, $password, $fullName, $phone );); // ...// ... }}
  • 47. <?php<?php classclass UserCreatorUserCreator {{ privateprivate $usersRepository;$usersRepository; privateprivate $emailNotifier;$emailNotifier; public functionpublic function __construct__construct(( UsersRepositoryUsersRepository $usersRepository,$usersRepository, NewAccountNotifierNewAccountNotifier $emailNotifier)$emailNotifier) {{ $this$this->->usersRepositoryusersRepository == $usersRepository;$usersRepository; $this$this->->emailNotifieremailNotifier == $emailNotifier;$emailNotifier; }} public functionpublic function registerNewUserregisterNewUser(( EmailEmail $email,$email, PasswordPassword $password,$password, stringstring $fullName,$fullName, PhoneNumberPhoneNumber $phone$phone == nullnull)) {{ $user$user == newnew UserUser($email, $password, $fullName, $phone);($email, $password, $fullName, $phone); $this$this->->usersRepositoryusersRepository->->insert($user);insert($user); $this$this->->emailNotifieremailNotifier->->sendNotification($user);sendNotification($user); }} }}
  • 48. <?php<?php // ...// ... public functionpublic function registerNewUserregisterNewUser(( EmailEmail $email,$email, PasswordPassword $password,$password, stringstring $fullName,$fullName, PhoneNumberPhoneNumber $phone$phone == nullnull)) {{ $user$user == newnew UserUser($email, $password, $fullName, $phone);($email, $password, $fullName, $phone); $this$this->->usersRepositoryusersRepository->->insert($user);insert($user); $this$this->->eventManagereventManager->->trigger(trigger('NewAccountCreated''NewAccountCreated', $user);, $user); }}
  • 49. <?php<?php // ... Confirguration// ... Confirguration $eventManager$eventManager->->on(on('NewAccountCreated''NewAccountCreated',, functionfunction ((UserUser $user) {$user) { $emailNotifier$emailNotifier == newnew NewAccountNotifierNewAccountNotifier();(); $emailNotifier$emailNotifier->->sendNotification($user);sendNotification($user); });});
  • 50. Some good advicesSome good advices ● Do not put “Entity” in your entities class namesDo not put “Entity” in your entities class names ● Avoid placing “Manager” or “Service” in theAvoid placing “Manager” or “Service” in the class names of your service layer classesclass names of your service layer classes ● One service class should not contain moreOne service class should not contain more then 3 dependenciesthen 3 dependencies
  • 51. We want more examples!We want more examples!
  • 52. We have this desktop application which weWe have this desktop application which we were using for our customers. We need to bringwere using for our customers. We need to bring all of the existing user profiles from there to theall of the existing user profiles from there to the web systemweb system
  • 53.
  • 54.
  • 55.
  • 56. We are braking the singleWe are braking the single responsibility principle... badly!responsibility principle... badly!
  • 57. The class is named “UserCreator”The class is named “UserCreator” …… notnot UserCreatorAndImporterFromSomewhereElUserCreatorAndImporterFromSomewhereEl sese
  • 58.
  • 60. We want our customers to be able toWe want our customers to be able to use Facebook for their registrationsuse Facebook for their registrations
  • 61.
  • 62.
  • 63. Grouping and packagingGrouping and packaging ● NEVER group by pattern (e.g. packageNEVER group by pattern (e.g. package Entities or Repositories)Entities or Repositories) ● Group by meaningGroup by meaning
  • 64. Get ready for endless refactoring!Get ready for endless refactoring!
  • 65. Admit your mistakes before yourself!Admit your mistakes before yourself!
  • 66. More on this topicMore on this topic
  • 67. More on this topicMore on this topic
  • 68. Thanks for listening!Thanks for listening! Contacts:Contacts: ● joan.grigorov@gmail.comjoan.grigorov@gmail.com ● @YoanDev@YoanDev ● http://linkedin.com/in/yoangrigorovhttp://linkedin.com/in/yoangrigorov