Les objets-valeurs (Value Object)

Cet article a été publié depuis plus de 6 mois, cela signifie que le contenu peut ne plus être d'actualité.

Tout récemment, nous avons eu un gros débat sur la conception d'un projet sur lequel je travaille. Le débat portait sur l'utilisation ou non d'un objet de type Objets-Valeur (ou Value Object en anglais). Il est vrai que dans l'environnement PHP l'utilisation de ce type d'objet est plutôt rare et méconnu (il est plus courant de voir utiliser des tableaux associatifs).

Les objets de type Objets-Valeurs sont généralement des petits objets dont leur objectif est d'apporter une notion sémantique au code. Contrairement à un autre objet, on s'intéresse à son contenu (la valeur de ses attributs) plutôt qu'à sa référence. Ces derniers sont généralement immuables.

L'exemple par excellence est certainement le cas de la monnaie. Si vous souhaitez gérer une notion d'argent, la monnaie peut alors être géré au moyen d'un Objet-Valeur, qui pourrait être défini comme ci-dessous :

class Money
{
  /** @var int */
  private $amount;

  /** @var string */
  private $currency;

  /**
   * @param int    $amount
   * @param string $currency
   */
  public function __construct($amount, $currency)
  {
    $this->amount   = $amount;
    $this->currency = $currency;
  }

  /**
   * @return int
   */
  public function getAmount()
  {
    return $this->amount;
  }

  /**
   * @return float
   */
  public function getFormatedAmount()
  {
    return round($this->amount / 100, 2);
  }
}

Cette exemple correspond à une implémentation du pattern monnaie décrit par Martin Fowler.

Il est alors plus agréable et compréhensible de manipuler un objet représentant une donnée précise qu'une variable de type entier ou flottante ayant une faible sémantique.

Ce type d'objet est très utilisé dans une conception pilotée par le domaine (Domain Driven Design) où le code est fortement basé sur le domaine métier et la logique associée. Ils permettent alors d'avoir un code compréhensible et avec un minimum d'ambiguïté.

PS: si vous êtes intéressé par une implémentation d'un Objet-Valeur permettant de gérer les devises. Sebastian BERGMANN a écrit une implémentation complète en PHP.