Slide 1

Slide 1 text

POURQUOI LE DDD
 NE DEVRAIT RIEN CHANGER A VOTRE VIE

Slide 2

Slide 2 text

ABOUT ME ➤ Alexandre Balmes ➤ Independant Software Consultant ➤ Co-fondateur de Vanoix ➤ J’aime le PHP et il me le rends bien ➤ Twitter : @pockystar

Slide 3

Slide 3 text

AU COMMENCEMENT

Slide 4

Slide 4 text

“ C’est pas grave, je ferais l’introduction -Alexandre Balmes

Slide 5

Slide 5 text

J’AI UN PROBLEME

Slide 6

Slide 6 text

J’AI UN PROBLEME
 JE DOIS VOUS PARLER DE DDD

Slide 7

Slide 7 text

J’AI UN PROBLEME JE DOIS VOUS PARLER DE DDD EN PHP

Slide 8

Slide 8 text

id;
 }
 
 public function setTitle($title)
 {
 $this->title = $title;
 }
 
 public function getTitle()
 {
 return $this->title;
 }
 }


Slide 9

Slide 9 text

VERSUS

Slide 10

Slide 10 text

id;
 }
 }
 stuffId = $id;
 $this->title = $title;
 } public function getStuff() : array
 {
 return [
 "id" => $this->stuffId,
 "title" => $this->title,
 ];
 } }
 
 AppBundle\Entity: type: entity id:
 id:
 type: integer
 generator: { strategy: AUTO } App\Domain\Entity\Stuff:
 type: mappedSuperclass
 fields:
 title: { type: string }
 embedded:
 stuffId:
 class: App\Domain\ValueObject\StuffId

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

DOMAIN-DRIVEN DESIGN

Slide 13

Slide 13 text

HISTORIQUE ➤ Un homme : Eric Evans ➤ Un livre : Domain-Driven Design: Tackling Complexity in the Heart of Software (2003 - Addison Wesley) ➤ Une idéologie : DDD => Software Craftsmanship => XP => TDD

Slide 14

Slide 14 text

“Leading software designers have recognized domain modeling and design as critical topics for at least 20 years, yet surprisingly little has been written about what needs to be done or how to do it. Although it has never been formulated clearly, a philosophy has emerged as an undercurrent in the object community, a philosophy I call domain-driven design. -Eric Evans

Slide 15

Slide 15 text

OBJECTIFS ➤ Comprendre le métier du client ➤ Modéliser le métier ➤ Retranscrire le vocabulaire

Slide 16

Slide 16 text

POURQUOI ? ➤ Le coeur d’une application c’est son métier (= son Domain) ➤ L’interface graphique, les services tiers peuvent régulièrement changer mais le métier beaucoup moins ➤ Le métier peut évoluer, stagner, disparaitre mais il ne devrait pas être “réinitialisé”

Slide 17

Slide 17 text

CONSEQUENCES ➤ Le DDD est une boite à outil : ➤ SOLID ➤ regroupant des bonnes pratiques de conception ➤ permettant la communication entre porteur de projet et développeurs à travers un language commun

Slide 18

Slide 18 text

PLUTÔT NORMAL NON ?

Slide 19

Slide 19 text

id;
 }
 public function setTitle($title)
 {
 $this->title = $title;
 }
 public function getTitle()
 {
 return $this->title;
 }
 }
 ALORS POURQUOI ?

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

QUESTIONS !

Slide 22

Slide 22 text

EST-IL ACCEPTABLE 
 POUR VOUS DE :

Slide 23

Slide 23 text

PASSER DES HEURES A ESSAYER DE DECRYPTER DU CODE ?

Slide 24

Slide 24 text

DE NE PAS POUVOIR DEVELOPER CERTAINES FONCTIONNALITÉS SOUS PRETEXTE DE ?

Slide 25

Slide 25 text

D’ETRE BLOQUÉ PAR LA TECHNO ?

Slide 26

Slide 26 text

DES IDÉES SIMPLES Qui changent un peu la vie

Slide 27

Slide 27 text

UBIQUITOUS LANGUAGE ➤ “N’importe quel utilisateur” doit pouvoir comprendre le code ➤ Le code doit refléter le language du métier, son vocabulaire, ses termes… ➤ Il faut chercher les experts métiers et les confronter au code ➤ Le business comprend le dévelopeur, le dévelopeur comprends le business

Slide 28

Slide 28 text

LAYERED ARCHITECTURE User Interface Application Domain Infrastructure Form Specification Service Entity
 ValueObject Enum
 DomainEvents Bridge
 CQRS
 Listener
 Persistence DTO
 Serializer … Service
 Repository … Services
 Mailer
 … Controller Action Responder

Slide 29

Slide 29 text

BOUNDED CONTEXT ➤ Une information n’a pas de sens sans contexte, ➤ Il est important de décomplexifier une application en la segmentant suivant ses contextes ➤ Une “Context map” permet de savoir qui travaille avec qui et de quelle manière (les collaborateurs) ➤ ProTip : Un channel monolog par contexte (plus d’info : http://www.slideshare.net/ javier.eguiluz/new-symfony-tips-tricks-symfonycon-paris-2015)

Slide 30

Slide 30 text

ITERATIVE DEVELOPMENT ➤ De l’agile tout simplement ➤ Chaque modification du language peut provoquer : ➤ Une modification du Domain ➤ L’ajout d’un contexte ➤ Du code d’Infrastructure ou d’Application en plus ou en moins ➤ …

Slide 31

Slide 31 text

C’EST CA LE DOMAIN-DRIVEN DESIGN

Slide 32

Slide 32 text

MISE EN PRATIQUE Des patterns que l’on devrait tous utiliser

Slide 33

Slide 33 text

“ Moi quand je veux écrire une page, je met d’abord son titre et sa description puis je remplis son contenu. - Jane Doe

Slide 34

Slide 34 text

“ Moi quand je veux écrire une page, je met d’abord son titre et sa description puis je remplis son contenu. - Jane Doe Auteur Action Constructeur Propriétés

Slide 35

Slide 35 text

Page __construct(Author $author, string $title, string $description) writeContent(string $content) Author __construct(string $author) getValue() : string isSatisfiedBy() : boolean CreatePageAction::__invoke(ServerRequestInterface $request) UserInterface Domain

Slide 36

Slide 36 text

Page __construct(Author $author, string $title, string $description) writeContent(string $content) Author __construct(string $author) getValue() : string isSatisfiedBy() : boolean CreatePageAction::__invoke(ServerRequestInterface $request) UserInterface Domain PageService::create(string $author, string, $title, $string description) Infrastructure

Slide 37

Slide 37 text

Page __construct(AuthorId $uid, Author $author, string $title, string $description) writeContent(string $content) CreatePageAction::__invoke(ServerRequestInterface $request) UserInterface Domain PageService::create(string $author, string, $title, $string description) Infrastructure PageRepository::__construct(Page::class) getClassName() : string save() Author + AuthorId __construct(string $author) getValue() : string isSatisfiedBy() : boolean NewPageHasBeenCreatedEv ent::__construct(Page $page)

Slide 38

Slide 38 text

CreatePageAction::__invoke(ServerRequestInterface $request) UserInterface Domain PageService::create(CreatePageDTO $dto) Infrastructure CreatePageDTO::__construct(string $author, string $title, string $description) Page __construct(AuthorId $uid, Author $author, string $title, string $description) writeContent(string $content) PageRepository::__construct(Page::class) getClassName() : string save() Author + AuthorId __construct(string $author) getValue() : string isSatisfiedBy() : boolean NewPageHasBeenCreatedEv ent::__construct(Page $page) Application

Slide 39

Slide 39 text

Application + UI Domain Infrastructure CreatePageCommand::__construct(Author $author, string $title, string $description) CreatePageHandler::handle(CreatePageCommand $command) PageService::create(CreatePageDTO $dto) PageWriteRepository::__construct(Page::class) getClassName() : string Page __construct(AuthorId $uid, Author $author, string $title, string $description) writeContent(string $content) Author + AuthorId __construct(string $author) getValue() : string isSatisfiedBy() : boolean NewPageHasBeenCreatedEv ent::__construct(Page $page)

Slide 40

Slide 40 text

“ Pour lire une page, il faut qu’elle soit publiée - Jane Doe

Slide 41

Slide 41 text

“ Pour lire une page il faut qu’elle soit publiée - Jane Doe Action Propriété Méthode

Slide 42

Slide 42 text

Page __construct(Author $author, string $title, string $description) writeContent(string $content) publish() read() : array Author __construct(string $author) getValue() : string isSatisfiedBy() : boolean ReadPage::__invoke(ServerRequestInterface $request) UserInterface Domain

Slide 43

Slide 43 text

Page __construct(Author $author, string $title, string $description) writeContent(string $content) publish() read() : array Author __construct(string $author) getValue() : string isSatisfiedBy() : boolean ReadPage::__invoke(ServerRequestInterface $request) UserInterface Domain PageService::read(PageId $id) : Page Infrastructure PageRepository::__construct(Page::class) getClassName() : string findById(PageId $id) : Page

Slide 44

Slide 44 text

ReadPage::__invoke(ServerRequestInterface $request) UserInterface Domain PageService::read(PageId $id) : Page Infrastructure PageORMRepository::__construct(ObjectManager $manager, Page::class) getClassName() : string findById(PageId $id) : Page PageIsReadableSpecification::isSatisfiedBy(Page $page) : boolean Application

Slide 45

Slide 45 text

ET MON BUNDLE/PLUGIN/MODULE ?

Slide 46

Slide 46 text

HEXAGONAL Infrastructure Application DOMAIN Adapter
 /Bridge Adapter
 /Bridge Adapter
 /Bridge Adapter
 /Bridge Adapter
 /Bridge Adapter
 /Bridge Persistence Mailer Listener CQRS API Client Bundle
 Plugin
 Module

Slide 47

Slide 47 text

ET MON SYMFONY ? ➤ Adoptez PSR-4 ! {
 "name": "black-project/black-standard-edition",
 "license": "MIT",
 "type": "project",
 "description": "The \"Black Edition\" distribution build on top of \"Symfony Standard Edition\"",
 "autoload": {
 "psr-4": {
 "Black\\Website\\": "src/Website/",
 "Black\\Bundle\\WebsiteBundle\\": "src/Website/Infrastructure/Bridge/Symfony/ WebsiteBundle/"
 },
 "classmap": [ "app/AppKernel.php", "app/AppCache.php" ]
 }, // Stuff }

Slide 48

Slide 48 text

MON DDD Le mien à moi que j’aime

Slide 49

Slide 49 text

SYMFONY-LESS

Slide 50

Slide 50 text

SYMFONY-LESS ➤ Mais utilisant des composants Symfony ➤ Mais pouvant être facilement encapsulé dans Symfony ou autre chose (via les Bridge) ➤ Mais surtout pouvant être utilisé dans un Middleware ➤ Puli : Universal Packages for PHP (Resource access et discovery)

Slide 51

Slide 51 text

SYMFONY-LESS ➤ Directory structure : ➤ src/Application//[…] ➤ src/Domain//[…] ➤ src/Infrastructure//[…] ➤ res/config ➤ res/views

Slide 52

Slide 52 text

PHP7 FOR THE WIN

Slide 53

Slide 53 text

PHP7 FOR THE WIN ➤ PHP7 est version majeure ➤ Improved performance: PHP 7 is up to twice as fast as PHP 5.6 ➤ Significantly reduced memory usage ➤ Abstract Syntax Tree ➤ Many fatal errors converted to Exceptions ➤ Secure random number generator ➤ The null coalescing operator (??) ➤ Return and Scalar Type Declarations ➤ Anonymous Classes

Slide 54

Slide 54 text

PHP7 FOR THE WIN ➤ PHP7 est version majeure ➤ Improved performance: PHP 7 is up to twice as fast as PHP 5.6 ➤ Significantly reduced memory usage ➤ Abstract Syntax Tree ➤ Many fatal errors converted to Exceptions ➤ Secure random number generator ➤ The null coalescing operator (??) ➤ Return and Scalar Type Declarations ➤ Anonymous Classes

Slide 55

Slide 55 text

PSR-7 FOR THE WIN

Slide 56

Slide 56 text

PSR-7 FOR THE WIN ➤ Standardisation des échanges : ➤ La requête : ServerRequestInterface ➤ La réponse : ResponseInterface ➤ Une URI : UriInterface ➤ Un fichier uploadé : UploadedInterface
 ➤ Utilisé dans notamment : ➤ Slim3 ➤ Zend3 : Stratigility/Diactoros/Expressive ➤ Symfony via symfony/psr-http-message-bridge

Slide 57

Slide 57 text

ACTION - DOMAIN - RESPONDER

Slide 58

Slide 58 text

ACTION - DOMAIN - RESPONDER ➤ J’ai dit bye bye au MVC : ➤ Un contrôleur -> X actions avec toutes les dépendances = mauvaise idée ➤ Un contrôleur -> 1 action avec ses propres dépendances = meilleure idée

Slide 59

Slide 59 text

ACTION - DOMAIN - RESPONDER ➤ J’ai dit bonjour à l’ADR : ➤ Déjà le naming est “parlant” ➤ Une Action de type Callable dont l’objectif est de traiter une requête et d’interagir avec le Domain ➤ Un Responder de type Callable dont l’objectif est de présenter les données provenants de l’Action ➤ C’est possible avec Symfony depuis la version 2.6

Slide 60

Slide 60 text

BDD/SPECBDD DOMAIN MODELING

Slide 61

Slide 61 text

No content

Slide 62

Slide 62 text

CONCLUSION Si je devais résumer

Slide 63

Slide 63 text

J’AIME LE DDD

Slide 64

Slide 64 text

PARCE QU’IL DONNE DU SENS 
 A MON TRAVAIL SUR LE LONG TERME

Slide 65

Slide 65 text

PARCE QU’IL CADRE
 MON CODE
 SUR LE LONG TERME

Slide 66

Slide 66 text

PARCE QUE MES CLIENTS
 APPRECIENT DE PARTAGER

Slide 67

Slide 67 text

DES MOMENTS JE NE 
 FAIS PAS DE DDD

Slide 68

Slide 68 text

J’UTILISE LES BONNES IDEES DU DDD DANS UN CONTEXTE PRECIS

Slide 69

Slide 69 text

J’UTILISE DES DESIGN PATTERNS MIS EN AVANT DANS LE DDD

Slide 70

Slide 70 text

ET CA FONCTIONNE TRÈS BIEN

Slide 71

Slide 71 text

J’AIME SYMFONY/SYMFONY

Slide 72

Slide 72 text

C’EST GRACE A LUI (EUX) QUE JE SUIS DEVANT VOUS

Slide 73

Slide 73 text

MAIS JE NE PEUX PAS
 MISER MA CARIERE SUR SYMFONY

Slide 74

Slide 74 text

PARCE QUE LE METIER DETERMINE LES OUTILS PAS L’INVERSE

Slide 75

Slide 75 text

MERCI