# 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é ? ```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) --- ### 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 { private $id; private $content; public function __construct(string $content) { $this->content = $content; } // getters } ``` Notes: - intégrité du domaine - Pas de setters par défaut, ni Doctrine ni sf n'en ont besoin --- ### Les règles métier ```php class Article { private $id; private $content; public function __construct(string $content) { if (empty($content)) { throw new ArticleHasNoContent(); } $this->content = $content; } // 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)); } } ``` --- # Emoji test 💩 Note: speaker notes FTW!