Pour ce premier billet, je souhaitais parler d’un patron de conception moins connu que les autres, à savoir le Value Object.

Value Object ?

Identité

Le value object est un simple objet, comme de l’argent, une adresse ou encore une date où la comparaison n’est pas basée sur son identité.

En PHP par exemple (mais c’est valable dans d’autres langages OO), les objets sont comparés sur leur identité :

Le premier test donne true car les 2 instances ont la même classe, mais la seconde false car ces 2 objets n’ont pas la même identité.

Immutable

Ensuite, un value object est un objet ‘immutable‘, c’est à dire qu’une fois créé, il ne sera plus possible de le modifier.

Par exemple : Vous avez une classe Personne dans votre code, qui a un attribut Adresse (un value object, admettons 44 rue de l’église). Vous faites déménager cette personne, aussi son adresse va changer. Mais au lieu de modifier cette adresse, il faudra alors en créer une autre, car le 44 rue de l’église existe toujours. Modifier cette adresse serait un non sens, c’est juste qu’elle ne sera plus attribuée à la même personne.

Les conséquences de cette ‘immutabilité’ : Pas de setters !

Un petit exemple

Ici, la classe Money représente de l’argent. Elle ne sert à rien pour le moment, c’est vrai.

Notez que cette fois, la comparaison renvoie false car les 2 objets n’ont pas la même valeur dans l’attribut amount.

Les avantages

Je vois plusieurs bénéfices à cette utilisation :

  • La plus grande selon moi est que cela permette de passer les tests de validation à chaque instant. Par exemple pour notre classe, rien n’empêche de tester dans le constructeur si amount est bien un nombre (c’est même recommandé 😉 ).
  • Ensuite, tout le monde sait de quoi on parle. Si vous travaillez en équipe, chaque dév saura qu’il s’agit de la classe Money. Si vous bossez seul, votre IDE vous proposera quand même l’auto-complétion ^^
  • Enfin, et non des moindres, cette méthode permet de faire du type hinting, c’est à dire de forcer à passer un objet particulier à une fonction ou une classe.

Un cas concret

Imaginons maintenant un cas réel : Nous avons une classe Personne qui a un porte monnaie et souhaitons représenter l’argent qu’elle possède.

Sans value object, ça donnerait à peu près ça :

Je vous passe bien sûr les tests pour savoir si le montant en paramètre est bien un nombre etc.

Maintenant, avec les value objects :

Remarquez l’implémentation de __toString pour pouvoir récupérer la valeur de l’objet sans getter, ça fait plus propre 😉

Un peu plus loin…

En bonus, je vous propose un petit Gist spécialement créé pour l’occasion, avec quelques Value Object très simples : Gist : Value Object

Un débat sur JeuWeb concernant ce pattern m’a poussé à créer un autre exemple mettant en valeur la comparaison de 2 Value Objects lorsque ceux-ci possèdent une caractéristique particulière, comme une devise : Temperature Value Object .

En résumé

Le value object est très simple à mettre en place, et il offre plusieurs avantages non négligeables, comme la manipulation d’objet dont le comportement est bien défini, au lieu de tableaux associatifs impossibles à tester.

N’hésitez pas y aller de vos remarques !