Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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://afup.org/talks/3037-de-crud-a-ddd-comment-meetic-a-sauve-son-legacy
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 !

Jean-Marie Lamodière

October 25, 2019
Tweet

More Decks by Jean-Marie Lamodière

Other Decks in Programming

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

    View Slide

  2. Legacy
    Architecture n-tiers
    DDD + Hexagonal
    2002-2012
    2013
    2015

    View Slide

  3. WHY ?
    Legacy, une fatalité ?
    Fait tourner la boîte
    Difficile à comprendre
    Maintenance coûteuse
    Icons made by Freepik from www.flaticon.com
    +
    -
    -

    View Slide

  4. Legacy
    Architecture n-tiers
    DDD + Hexagonal
    2002-2012
    2013
    2015

    View Slide

  5. WHY ?
    Architecture n-tiers
    Presentation (Apps)
    Presentation
    Logique métier
    Données
    Icons made by Smashicon from www.flaticon.com

    View Slide

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

    View Slide

  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*

    View Slide

  8. Legacy
    Architecture n-tiers
    DDD + Hexagonal
    2002-2012
    2013
    2015

    View Slide

  9. WHY ?
    Icons made by Freepik, Roundicon from www.flaticon.com
    Différence DDD / Hexagonal ?
    /Application
    /Command
    /Query
    /Domain
    /Read
    /Infrastructure
    /Symfony
    /Persistence

    View Slide

  10. Domain
    Driven
    Design
    Eric Evans - 2004

    View Slide

  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

    View Slide

  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
    ● ...

    View Slide

  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”

    View Slide

  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

    View Slide

  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

    View Slide

  16. WHY ?Notion métier implicite
    $member
    ->setFoo()->setBar()
    //...
    // Activate the member
    ->setStatus(‘active’)
    ->setActivationDate($now)
    ->setCanTalk(true);

    View Slide

  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

    View Slide

  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

    View Slide

  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);

    View Slide

  20. Icons made by Roundicons from www.flaticon.com
    Primitive obsession
    $product
    ->setPriceAmount(20.50)
    ->setCurrenty(“EUR”);
    (vont ensemble)

    View Slide

  21. WHY ? Value Object DDD
    $price =
    new Price(20.50, “EUR”);
    $product
    ->setPrice($price);
    ● Explicite
    ● Immutable
    ● Valide

    View Slide

  22. WHY ?
    Value Object DDD @ Meetic
    $age = new Age(23);
    … = $age
    ->toSearchBirthdayMax();
    ● Factorise la validation
    ● Factorise des fonctionnalités
    >= 18

    View Slide

  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

    View Slide

  24. WHY ?
    Command Query Separation
    /Application
    /Command
    RegisterMember
    /Query
    GetNewMembers
    /Domain
    MemberRepositoryInterface
    Member
    Age

    View Slide

  25. Hexagonal Architecture
    Ports & Adapters
    Clean architecture
    ...
    Dr. Alistair Cockburn - 2005

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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”

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  36. Chemin de migration
    Icons made by Freepik from www.flaticon.com

    View Slide

  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

    View Slide

  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 !

    View Slide

  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

    View Slide