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

Symfony2 : un framework orienté Domain Driven Design ?

Symfony2 : un framework orienté Domain Driven Design ?

Jean-François Lépine

November 05, 2013
Tweet

More Decks by Jean-François Lépine

Other Decks in Programming

Transcript

  1. Symfony2 :
    un framework orienté DDD ?
    Jean-François Lépine – Novembre 2013

    View Slide

  2. En face de vous

    Jean-François Lépine

    Consultant PHP chez Alter Way

    @Halleck45

    http://blog.lepine.pro

    View Slide

  3. Ce qu'on va aborder

    Rappel rapide de ce qu'est Symfony2

    Rappel un peu moins rapide de ce que c'est que le DDD

    Symfony2 et Doctrine2 sont-ils orientés DDD ?

    Retours d'expériences de deux projets DDD avec Symfony2

    View Slide

  4. Piqûre de rappel

    View Slide

  5. Symfony 2

    Communauté très active

    Open Source

    Support
    – Gratuit (6 mois, ou 2 ans pour les LTS)
    – Payant (3 ans)

    Framework
    – Full stack
    – Composants

    View Slide

  6. Des outils

    BrowserKit

    ClassLoader

    Config

    Console

    CssSelector

    Debug

    DependencyInjection

    DomCrawler

    EventDispatcher

    Filesystem

    Finder

    Form

    HttpFoundation

    HttpKernel

    Locale

    Intl

    Icu

    OptionsResolver

    Process

    PropertyAccess

    Routing

    Security

    Serializer

    Stopwatch

    Templating

    Translation

    Validator

    Yaml

    View Slide

  7. Une philosophie

    Orienté Requête / Réponse

    Ne pas réinventer la roue :

    Twig

    PHPUnit

    KISS (ou presque)

    Tout est « Bundle »

    KnpBundles.com : 2 000 bundles !

    View Slide

  8. Un cadre de travail

    Conventions de code

    Bonnes pratiques (injection de dépendances, etc. )

    PSR (nommage, logs, etc.)

    Cadre « devops »

    Déploiement (capistrano / capifony)

    Cache HTTP, tags ESI...

    View Slide

  9. Domain Driven design

    View Slide

  10. Une démarche de travail

    Le code source est le reflet du besoin fonctionnel

    Le code source adopte le vocabulaire fonctionnel

    Le code source facilite :
    – Le changement
    – La gestion des règles métiers
    – La maintenabilité

    View Slide

  11. Une langue commune

    Eviter les ambiguïtés

    Est élaborée en commun

    Est parlée par tous

    Glossaire du projet
    UBIQUITOUS
    LANGAGE

    View Slide

  12. Entité

    Est unique

    Est identifiable

    Son identité est immutable

    View Slide

  13. Aggrégat

    Représente une ≈Collection
    d'entités

    Se manipule comme s'il s'agissait
    d'une seule Entité

    View Slide

  14. Repository

    Permet de retrouver et de persister les entités

    View Slide

  15. Service et Spécification
    Service

    Exerce les Comportements métiers

    Est un service purement fonctionnel
    (pas de classe outils)
    Spécification

    Représente une règle métier
    $dog=new Dog;
    $rule=new CanBeSoldSpecification;
    if($rule­>isSatisfedBy($dog)) {
    // ...
    }

    View Slide

  16. Objet valeur

    Représente une Information

    Est immutable

    Un identifiant

    Une Date

    Un Montant

    Une Adresse

    ...

    View Slide

  17. Isolation

    View Slide

  18. Spécialisation

    View Slide

  19. Testabilité

    View Slide

  20. Testabilité

    View Slide

  21. Keep It Simple and Stupid !

    Un objet simple par règle métier

    La complexité se fait par
    l'assemblage de composants simples
    et réutilisables

    View Slide

  22. Doctrine 2 et DDD

    View Slide

  23. Au fait...

    « DDD is not about framework or
    tools... »

    View Slide

  24. Doctrine 2 et DDD

    View Slide

  25. Doctrine 2

    Doctrine 2 contient en partie le vocabulaire du DDD

    Entities

    Repositories

    ObjectValue (DbalTypes)

    Aggregates (Collection)

    S'agit-il des mêmes concepts que le DDD ?

    View Slide

  26. Doctrine 2, outil du DDD ?
    Oui

    Entité

    Repository
    Peut-être

    Aggrégat

    Identifiants
    Non

    Object Value

    View Slide

  27. Doctrine 2 et Objet valeur

    En théorie, les DbalTypes sont des Objets Valeur

    En pratique, les Objets Valeurs sont des entités spécifiques

    Doctrine 2 gère difficilement les Types complexes (ex : une adresse, elle même composée de rue, ville, etc.)

    Doctrine 2 permet difficilement de serializer des DbalTypes autrement qu'en String

    View Slide

  28. Doctrine 2 et Aggrégat

    En théorie, il est possible de déterminer comment une Collection sera persistée

    En théorie, il est possible d'utiliser des Collections personnalisées à la place des
    Collection Doctrine

    En pratique, pour être viable, il faut un peu d'investissement

    View Slide

  29. Doctrine 2 et Identifiants

    Doctrine2 ne pousse pas assez à l'utilisation de vrais identifiants :

    La systématisation de l'utilisation de vrais Identifiants ne fait pas partie de
    Doctrine2
    class UserRepository {
    public function getById(UserId $id) {
    }
    }

    View Slide

  30. Symfony2 et DDD

    View Slide

  31. Symfony2, outil du DDD ?
    Oui

    Atomisation des
    comportements

    Anonymisation du
    framework
    Peut-être

    Couplage et Cohésion
    Non

    Validation des
    données

    Service ≠ Service

    Architecture de base

    View Slide

  32. Oui : atomisation, anonymisation

    Atomisation

    Les framework pousse au respect des principes SOLID

    Anonymisation

    L'injection de dépendances + utilisation d'alias permet d'écrire du code « sans framework »
    services:
    domain.acl.provider:
    alias: acl_provider
    services:
    mon.domain.service:
    arguments:
    ­ domain.acl.provider

    View Slide

  33. Peut-être : cohésion et couplage

    En théorie, il est possible d'écrire du code totalement indépendant du
    framework

    En réalité, le code est écrit dans un cadre (framework)

    En réalité, ce n'est pas grave pour les couches Application et Infrastructure

    View Slide

  34. Non : validation de données

    Validation dans Symfony2 = JSR 303 (Bean Validation)
    1. Les objets contiennent des règles de validation
    2. Les objets sont remplis avec les données à valider (potentiellement invalides)
    3. Les objets sont validés

    Une entité doit toujours être dans un état valide

    Le processus classique de validation de données dans Symfony2 introduit une
    complexité forte dans la logique DDD

    View Slide

  35. Non : service

    Service Symfony2 ≠ Service DDD

    La confusion due au vocabulaire est très difficile à surmonter, même pour des
    développeurs confirmés

    View Slide

  36. Non : architecture

    Plus grosse difficulté pour le DDD

    Où placer mes entités ?

    Comment séparer mes couches ? Dans un seul
    bundle ? Dans plusieurs bundles ?

    Mon domain est-il un Bundle comme
    un autre ?

    View Slide

  37. du DDD avec Symfony2
    Retour d'expériences

    View Slide

  38. A la recherche du Graal

    Pas mal de tentatives différentes

    Pas de solution miracle jusqu'ici

    View Slide

  39. Projet 1

    Gros projet Alter Way, > 1000 jours / homme

    5 dépôts GIT

    UserInterface : BackboneJS

    Application : Contrôleurs Symfony2, ApiResource, Forms

    Model : Entités et Déclaration d'entités Doctrine2

    Domain : Services et Spécifications métier Symfony2

    Infrastructure : outils

    Tout est Bundle

    View Slide

  40. Projet 1 : refractoring

    Au bout de 6 mois, refractoring
    important

    2 dépôts Git :

    Front-end BackboneJS

    Back-end Symfony2

    View Slide

  41. Au bout d'un an

    Ambiguïté sur la notion de « Bundle »

    Couplage assez fort entre le Domain et Symfony2

    Globalement viable et de bonne qualité

    View Slide

  42. Projet 2

    2 dépôts Git :

    Front-end AngularJs

    Back-end Symfony2, PHP

    Des bundles

    UiApi et UiCli

    Sécurité

    Liaison DDD / Sources

    Une librairie DDD (contrats)

    Des sources métier

    View Slide

  43. Symfony2++

    Contexte fonctionnel dans Symfony2 :

    Introduction de la notion d' « Acteur » (ou Agent)

    Renforcement de l'utilisation d'Evénements
    public function activateProjectAction(Project $project, Context $context) { }
    public function editAction(Project $project, EditableContext $context) { }

    View Slide

  44. Symfony2++

    Plus de DQL, mais des décorateurs de Critères :
    /**
    * @Criteria(for="users",
    criteria="Acme\...\Criteria\UsersOfProject",
    service="acme.projects.service
    )
    */
    public function userstAction(Project $user, UserCollection $users) { }
    class UsersOfProject extends Criteria
    {
    public function apply($queryBuilder)
    {
    $project = $this­>bag­>getProject();
    $queryBuilder­>field('projects.$id')­>equals($project­>getId());
    }
    }

    View Slide

  45. Difficultés

    Il a fallu tout externaliser

    Par exemple :

    Il faut parfois se battre avec la logique Symfony2 / Doctrine

    Ex : ACL peu évolutifs
    doctrine_mongodb:
    connections:
    mappings:
    model:
    type: yml
    dir: %kernel.root_dir%/../../src/Acme/Application/Mapping
    prefix: Hal\Manage\Crm\Domain
    alias: Acme\Domain
    is_bundle: false

    View Slide

  46. Difficultés

    Nécessite des compétences avancées

    Et en Symfony2

    Et en POO

    View Slide

  47. Au bout d'un an (ou presque)

    Couplage très faible entre le framework et Symfony 2

    Couche Domain très « propre »

    Une grande question :

    View Slide

  48. Une grande question

    « Mais pourquoi utiliser Symfony2 framework plutôt que Component ou Silex !?! »

    Confusion entre Framework et outils

    « Projet 3 » en cours

    1 dépôt UI : AngularJs

    1 dépôt Application : Symfony2 Framework

    1 dépôt Domain : PHP

    1 dépôt Infrastructure : Symfony2 Component

    View Slide

  49. Conclusion

    View Slide

  50. Symfony2 et DDD

    Symfony2 n'est pas vraiment orienté DDD

    Symfony2 + Doctrine2 se prête assez bien au DDD

    Mais ce ne sont PAS des recettes miracle

    Peuvent être des freins

    Doivent être détournés

    Nécessitent un bon niveau technique

    View Slide

  51. Merci !

    C'est l'heure des questions

    Et de la pub:-)

    http://communiquez.lepine.pro : eBook open source sur le Bevahior Driven Development)

    View Slide