Entités, objets-valeurs et agrégats
« Tout est objet » ne dit pas quoi protéger : l'agrégat dit quelles règles tiennent ensemble et où passe la frontière transactionnelle.
Prérequis : cours 3.1 ; entités et relations.
Pourquoi
« Tout est objet » ne dit pas quoi protéger : l'agrégat dit quelles règles tiennent ensemble et où passe la frontière transactionnelle. Sans lui : invariants violés, transactions géantes, concurrence qui casse.
Concepts
- Entité : a une identité qui persiste (
Order #1234reste elle-même même si tout change). Égalité par id. - Objet-valeur (VO) : défini par ses attributs (
Money(10, EUR),Email), immuable, égalité par valeur. Remplace les strings/numbers nus qui traînent les bugs (moveMoney(10, "EUR")vsMoneytypé). - Agrégat : grappe cohérente avec une racine (seul point d'entrée) et des invariants (« une commande ne dépasse pas le crédit client »). On charge/modifie/sauve l'agrégat entier, en une transaction.
Exemple : l'invariant protégé
class Order { // racine d'agrégat
addLine(item) {
if (this.total() + item.price > this.customer.credit)
throw new CreditExceeded(); // invariant garanti quoiqu'il arrive
this.lines.push(item);
}
}
// Personne ne touche lines directement : la règle ne peut pas être contournée
Cas réel
Remises appliquées « à côté » de la commande (script promo direct en base) : totaux incohérents, compta fausse pendant 2 mois. Tout passe par la racine depuis : une seule porte, des invariants qui tiennent.
Pièges
- Agrégat = TOUT le graphe (« la commande et ses 10 000 lignes + le client ») : énorme = lent + conflits. Petit agrégat, références par id au dehors.
- VO mutable : un
Moneyqu'on modifie sur place propage des effets de bord. Immuable, toujours. - Setters publics sur l'entité : chaque setter est une porte de contournement des invariants.
À retenir
Entité = identité, VO = valeur immuable, agrégat = racine + invariants + une transaction.