Glossaire
Objet Valeur (Value Object)

Les objets de valeur sont des objets légers et immuables qui n'ont pas d'identité.

Bien que leurs valeurs soient plus importantes, ils ne sont pas de simples objets de transfert de données (DTO)

Les objets de valeur sont un bon endroit pour placer des calculs complexes, en déchargeant la logique de calcul lourde des entités.

Ils sont beaucoup plus faciles et plus sûrs à composer, et en déchargeant les entités de la logique de calcul lourde, ils aident les entités à se concentrer sur leur rôle de suivi du cycle de vie.

Certains attributs et comportements peuvent être déplacés hors de l'entité elle-même et placés dans des objets de valeur.

  • N'ont pas d'identité. L'égalité est déterminée par une propriété structurelle.
  • Sont immuables.
  • Ils peuvent être utilisés comme attributs d'entités et d'autres objets de valeur
  • Définissent et appliquent explicitement des contraintes importantes (invariants).

Les objets de valeur ne doivent pas être un simple regroupement commode d'attributs mais doivent former un concept bien défini dans le modèle de domaine.

Cela est vrai même s'il ne contient qu'un seul attribut. Lorsqu'il est modélisé comme un tout conceptuel, il est porteur de sens lorsqu'il est transmis et peut faire respecter ses contraintes.

Imaginez que vous ayez une entité Utilisateur qui a besoin de l'adresse d'un utilisateur. Habituellement, une adresse est simplement une valeur complexe qui n'a pas d'identité dans le domaine et qui est composée de plusieurs autres valeurs, comme le pays, la rue, le code postal etc..., elle peut donc être modélisée et traitée comme un Value Object avec sa propre logique métier.

Un objet de valeur n'est pas seulement une structure de données qui contient des valeurs. Il peut également encapsuler la logique associée au concept qu'il représente.

En savoir plus sur les Value Objects :

1
import { ValueObject } from './value-object.base';
2
import { Guard } from 'guard.base';
3
import { ArgumentOutOfRangeException } from './exceptions';
4
5
export interface AddressProps {
6
country: string;
7
postalCode: string;
8
street: string;
9
}
10
11
export class Address extends ValueObject<AddressProps> {
12
get country(): string {
13
return this.props.country;
14
}
15
16
get postalCode(): string {
17
return this.props.postalCode;
18
}
19
20
get street(): string {
21
return this.props.street;
22
}
23
24
protected validate(props: AddressProps): void {
25
if (!Guard.lengthIsBetween(props.country, 2, 50)) {
26
throw new ArgumentOutOfRangeException('country is out of range');
27
}
28
if (!Guard.lengthIsBetween(props.street, 2, 50)) {
29
throw new ArgumentOutOfRangeException('street is out of range');
30
}
31
if (!Guard.lengthIsBetween(props.postalCode, 2, 10)) {
32
throw new ArgumentOutOfRangeException('postalCode is out of range');
33
}
34
}
35
}