Skip to content
Snippets Groups Projects
index.md 2.76 KiB
Newer Older
  • Learn to ignore specific revisions
  • # Ne soyez plus l'esclave de Doctrine
    
    ---
    ## Hello!
    
    <div style="width: 50%; float: left;">
    Grégoire Paris
    </div>
    <div style="width: 50%; float: right;">
    Maxime Veber
    </div>
    
    ---
    ### Une application classique
    
    <pre style="width: 50%; float: left;">
    .
    ├── AppBundle
        ├── Admin
        ├── AppBundle.php
        ├── Controller
        ├── DataFixtures
        ├── DependencyInjection
        ├── Entity
        ├── Form
        ├── Listeners
        ├── OAuth
        ├── Resources
        ├── Tag
        └── Twig
    </pre>
    
    ---
    ### Vous avez dit entité ?
    
    Greg0ire's avatar
    Greg0ire committed
    
    ```php
    
    class TypicalArticle
    {
        private $id;
        private $content;
    
        public function getId() { return $this->id; }
        public function getContent() { return $this->content; }
        public function setContent($content)
        {
            $this->content = $content;
            return $this;
        }
    }
    ```
    
    Notes:
    - Pas de validation
    - Pas de règles métier
    - Aucune logique (pas de tests nécessaires)
    
    Greg0ire's avatar
    Greg0ire committed
    
    
    ---
    ### Nous aimons le DDD
    
    - Séparer le **domaine** de l'infrastructure
    - Représenter les **règles métier** dans les entités
    - Avoir une API expressive
    
    ---
    ### Doctrine n'a pas besoin de setters
    
    ```php
    class NotThatTypicalArticle
    
    Greg0ire's avatar
    Greg0ire committed
    {
    
        private $id;
        private $content;
    
        public function __construct(string $content)
        {
            $this->content = $content;
        }
    
        // getters
    
    Greg0ire's avatar
    Greg0ire committed
    }
    ```
    
    
    Notes:
    - intégrité du domaine
    - Pas de setters par défaut, ni Doctrine ni sf n'en ont besoin
    
    
    Greg0ire's avatar
    Greg0ire committed
    ---
    
    ### Les règles métier
    
    ```php
    class Article
    {
        private $id;
        private $content;
    
    Greg0ire's avatar
    Greg0ire committed
    
    
        public function __construct(string $content)
        {
            if (empty($content)) {
                throw new ArticleHasNoContent();
            }
            $this->content = $content;
        }
    
    Greg0ire's avatar
    Greg0ire committed
    
    
        // getters
    }
    ```
    
    Note:
    - Impossible de persister une entité invalide
    - Validation compliquée quand on a trop de propriétés
    
    - Pour qu'on puisse utiliser des constructeurs sans que ça crée de conflit avec
      Doctrine, Doctrine utilise de la réflection ou de la désérialisation pour
    hydrater les entités.
    
    
    ---
    ### Les value objects
    
    ```php
    class ArticleContent
    {
        private $content;
        private $lastModification;
    
        public function __construct(string $content)
        {
            if (empty($content)) {
                throw new ArticleHasNoContent();
            }
            $this->content = $content;
            $this->lastModification = new \DatetimeImmutable();
        }
    }
    ```
    
    Note:
    - Déportation de la validation dans les value objects
    - Début d'arborescence
    - Doctrine Embeddables
    - Custom types
    
    ---
    ### Les constructeurs nommés
    
    ```php
    class BetterArticle
    {
        public static function createFromNative(string $content)
        {
            return new self(new ArticleContent($content));
        }
    }
    
    ```
    
    ---
    
    Greg0ire's avatar
    Greg0ire committed
    # Emoji test
    
    💩
    
    Note:
    speaker notes FTW!