De CRUD à DDD, comment Meetic a sauvé son legacy

De CRUD à DDD, comment Meetic a sauvé son legacy

Vidéo : https://youtu.be/tdE5wE5MvsI
ForumPHP 2019 : https://event.afup.org/forumphp2019/programme/#3037
Joind.in : https://joind.in/talk/1c557

Maîtriser son framework, c'est bien ! Il vous aidera à gérer les besoins génériques sans ré-inventer la roue, comme mettre en place un CRUD (Create Read Update Delete).

Mais dès que votre logique métier devient complexe, il vous faudra de nouvelles compétences pour garder un code lisible et évolutif.

- Vos tests automatisés cassent au moindre refactoring, vous freinant au lieu de vous aider ?
- Votre code est complexe à prendre en main pour les nouveaux arrivants ?
- Mettre à jour la version de votre framework prend des proportions anormales ?

Chez Meetic, nous sommes passés par là ! Découvrez pourquoi et comment notre culture a évolué vers de nouvelles pratiques, comme le Domain Driven Design et l'architecture Port & Adapters, nous aidant par exemple à créer des tests enfin utiles ou à mieux dialoguer avec les spécialistes du métier.

Des pratiques utilisables tout au long de votre carrière, quelques soient les changements de framework ou de language que nous réservent l'avenir !

64822af642dacc617380f009e35a78f7?s=128

Jean-Marie Lamodière

October 25, 2019
Tweet

Transcript

  1. De CRUD à DDD Comment Meetic a sauvé son legacy

    Icons made by Icongeek26, Freepik from www.flaticon.com Jean-Marie Lamodière - Backend tech lead @jmlamodiere
  2. Legacy Architecture n-tiers DDD + Hexagonal 2002-2012 2013 2015

  3. WHY ? Legacy, une fatalité ? Fait tourner la boîte

    Difficile à comprendre Maintenance coûteuse Icons made by Freepik from www.flaticon.com + - -
  4. Legacy Architecture n-tiers DDD + Hexagonal 2002-2012 2013 2015

  5. WHY ? Architecture n-tiers Presentation (Apps) Presentation Logique métier Données

    Icons made by Smashicon from www.flaticon.com
  6. Appli Symfony toute neuve = Legacy v2 Icons made by

    Freepik from www.flaticon.com
  7. WHY ? Framework MVC = CRUD* Icons made by Smashicon,

    Freepik from www.flaticon.com 3. Resource REST = entité *Create Read Update Delete *https://github.com/symfony/symfony-docs/issues/8893 Presentation Logique métier Données 2. ??? 1. Entité (getters/setters) + BDD auto-générés*
  8. Legacy Architecture n-tiers DDD + Hexagonal 2002-2012 2013 2015

  9. WHY ? Icons made by Freepik, Roundicon from www.flaticon.com Différence

    DDD / Hexagonal ? /Application /Command /Query /Domain /Read /Infrastructure /Symfony /Persistence
  10. Domain Driven Design Eric Evans - 2004

  11. WHY ? Domain Driven Design “Rendre le domaine explicite dans

    le code pour favoriser le dialogue tech/produit” Icons made by Icongeek26, Freepik from www.flaticon.com
  12. WHY ? Domain Driven Design Patterns stratégiques Sous domaines :

    • Core • Supporting • Generic Bounded context Patterns Tactiques Organisation du code : • Entity • Value Objects • Domain events • ...
  13. WHY ? Bounded context • “Dans le contexte culinaire :

    • Dans le contexte botanique : • Dans le contexte du : est un légume est un fruit est un feedback”
  14. WHY ? Ubiquitous language “Language commun tech/produit au sein d’un

    bounded context” Défi : le placer dans le code :) Icons made by Icongeek26 from www.flaticon.com
  15. Temporal coupling $member ->setStatus(‘active’) ->setActivationDate($now) ->setCanTalk(true); Icons made by Roundicons

    from www.flaticon.com Feature envy Anemic domain model Entité CRUD
  16. WHY ?Notion métier implicite $member ->setFoo()->setBar() //... // Activate the

    member ->setStatus(‘active’) ->setActivationDate($now) ->setCanTalk(true);
  17. $member ->setStatus(‘active’) ->setActivationDate($now) ->setCanTalk(true); Icons made by Roundicons from www.flaticon.com

    Class MyService1 Class Member $member ->setStatus(‘active’) ->setActivationDate($now) ->setCanTalk(true); Class MyService2 Feature envy
  18. WHY ? $member = new Member(); //... $member->getActivationDate()->format(‘Y-m-d’); Fatal error:

    Uncaught Error: Call to a member function format() on null Icons made by Roundicons from www.flaticon.com Temporal coupling
  19. WHY ? Entité DDD Rich domain model Icons made by

    Roundicons from www.flaticon.com $member = Member::register(/*...*/); • Etat toujours valide • Mutators explicites • Emet des évènements $member->activate($now);
  20. Icons made by Roundicons from www.flaticon.com Primitive obsession $product ->setPriceAmount(20.50)

    ->setCurrenty(“EUR”); (vont ensemble)
  21. WHY ? Value Object DDD $price = new Price(20.50, “EUR”);

    $product ->setPrice($price); • Explicite • Immutable • Valide
  22. WHY ? Value Object DDD @ Meetic $age = new

    Age(23); … = $age ->toSearchBirthdayMax(); • Factorise la validation • Factorise des fonctionnalités >= 18
  23. $repo->persist($member)->flush; $repo->add($member); $member = $repo->get($memberId); $repo->increaseVueCounter($memberId); Repository DDD = “collection”

    Intention revealing interface Icons made by Roundicons, Freepik from www.flaticon.com
  24. WHY ? Command Query Separation /Application /Command RegisterMember /Query GetNewMembers

    /Domain MemberRepositoryInterface Member Age
  25. Hexagonal Architecture Ports & Adapters Clean architecture ... Dr. Alistair

    Cockburn - 2005
  26. WHY ? Le découplage ? Low coupling High cohesion “Mettre

    ensemble ce qui a la même raison de changer.” Icons made by Roundicons from www.flaticon.com
  27. WHY ? Architecture Hexagonale “Découpler les décisions métier et techniques”

    Icons made by Roundicons from www.flaticon.com Low coupling High cohesion
  28. WHY ? Ex. de refactos techniques @Meetic Symfony 2 Icons

    made by Freepik from www.flaticon.com Symfony 4 Database Oracle Database External REST API Config files PostgreSQL
  29. Port & Icons made by Freepik from www.flaticon.com Pas de

    framework Command Query MysqlRepository HttpRepository Framework ok TestRepository RestController Test CliController Repository Framework ok Adapter
  30. WHY ? Infrastructure : test d’intégration Icons made by Freepik,

    Smashicons, Roundicons from www.flaticon.com Ex. de refactoring : QueryBuilder -> SQL pure MysqlRepository Docker mysql HttpRepository Wiremock Don’t mock what you don’t own
  31. WHY ? Infra complexe en n-tiers Service métier MysqlDao* HttpDao*

    *Data Access Object “Entity” Connait les 2 DAO Icons made by Roundicon from www.flaticon.com “Entity”
  32. WHY ? Infra complexe en hexagonal UseCase RepositoryInterface Entity AggregatorRepository

    MysqlDao* HttpDao* *Data Access Object Pas d’impact Icons made by Freepik, Roundicon from www.flaticon.com
  33. Icons made by Smashicon from www.flaticon.com 3. Presentation N-Tiers Hexagonal

    2. Logique métier 1. Données 2. Presentation 1. Logique métier 2. Données
  34. WHY ? Icons made by Freepik from www.flaticon.com Arborescence Meetic

    /Application /Command RegisterMember /Query GetNewMembers /Domain MemberRepositoryInterface Member Age /Infrastructure /Symfony MemberController MemberSerializer /Persistence MysqlMemberRepository
  35. WHY ? Ou mettre mon code ? Infrastructure • Framework

    (+ version) • Libraries (Doctrine, Guzzle) • Base De Donnée • REST, SOAP, Ligne de cmd ? Domaine Logique métier Icons made by Icongeek26, Freepik from www.flaticon.com Product Owner Expert métier Architecte Dev, Ops
  36. Chemin de migration Icons made by Freepik from www.flaticon.com

  37. WHY ? Ne pas empiler des couches Lava flow Refacto

    tranche métier “verticale” Icons made by Freepik, Pixel Perfect, Roundicons from www.flaticon.com New layer Old layer 1 Old layer 2
  38. WHY ? Montrer l’exemple là ou c’est complexe Pas de

    DDD / Hexagonal si un CRUD suffit Rendre explicite une règle métier Animer des débats Pourquoi ? Fait comme ça !
  39. Domain Driven Design “Rendre le domaine explicite” Hexagonal Découpler les

    décisions métier et techniques Product Owner Expert métier Architecte Dev, Ops @jmlamodiere Icons made by Icongeek26, Freepik from www.flaticon.com Merci https://joind.in/talk/1c557