Newer
Older
# 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é ?
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.
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
---
### 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));
}
}
```
---