05-09-2015, 06:30 AM
(Modification du message : 05-09-2015, 06:38 AM par Max72.
Raison de la modification: Aération du code
)
Aargh, tu me fais bosser le samedi matin ^^
Egalité des attributs
Si le VO ne représente pas un simple nombre ou chaine (comme des € vs $ ), alors ça change la donne et pour chaque 'devise', il faut un VO.
Voilà comment j'implémenterai ton exemple :
Egalité des attributs
Si le VO ne représente pas un simple nombre ou chaine (comme des € vs $ ), alors ça change la donne et pour chaque 'devise', il faut un VO.
Voilà comment j'implémenterai ton exemple :
Code PHP :
<?php
interface ValueObjectInterface
{
public function getNative();
public function __toString();
public function isEqual(ValueObjectInterface $value);
}
class Real implements ValueObjectInterface
{
protected $value;
public function __construct($value)
{
$value = filter_var($value, FILTER_VALIDATE_FLOAT);
if ($value === false)
{
throw new InvalidArgumentException('value doit etre un nombre réel');
}
$this->value = $value;
}
public function getNative()
{
return $this->value;
}
public function __toString()
{
return strval($this->value);
}
public function isEqual(ValueObjectInterface $value)
{
if (!$value instanceof $this)
{
return false;
}
return ($this->getNative() === $value->getNative());
}
}
abstract class Temperature extends Real
{
abstract public function toCelsius();
abstract public function toFahrenheit();
}
class Celsius extends Temperature
{
public function toCelsius()
{
return new Celsius($this->value);
}
public function toFahrenheit()
{
return new Fahrenheit($this->value * 1.8 + 32);
}
}
class Fahrenheit extends Temperature
{
public function toCelsius()
{
return new Celsius(($this->value - 32) /1.8);
}
public function toFahrenheit()
{
return new Fahrenheit($this->value);
}
}
$cel = new Celsius(100);
$fah = new Fahrenheit(100);
echo $fah->toCelsius()->getNative();
// 37.777777777778
var_dump($fah->isEqual($cel));
// bool(false)
$other_fah = new Fahrenheit(212);
var_dump($other_fah->toCelsius()->isEqual($cel));
// bool(true)
J'ai mis ça sur un Gist si vous voulez : https://gist.github.com/Max-koder/75c8dffb511ca575c2da
Ici, si tu essayes de comparer 2 températures qui n'ont pas la même devise (je ne sais pas comment on dit ^^ ), ça te retourne false, logique.
Il faut passer par une conversion.
Bien entendu, j'aurai très bien pu mettre dans ma class Température des tests pour comparer automatiquement ces températures (avec des if instanceof Celsius , if instanceof Fahrenheit , mais il est tôt ^^ ).
Edit : Si tu n'es pas convaincu par cette méthode, j'en ai une autre en réserve :p
Mutable
Si tu as besoin de le muter, modifier, avoir un tas de méthode, c'est que tu n'as pas besoin d'un VO, mais d'un objet tout court.
L'article VOvsDTO
Pour moi, l'Adresse du perso est bien un VO, car je l'ai créé comme tel. Pas de setter, pas de méthode excepté getter/comparaison/constructor.
J'aurai très bien pu créer une classe comme Personnage et mettre des setters pour y modifier la rue etc, mais je ne l'ai pas fait, ce qui rend par définition ma classe
Adresse un Value Object
Enfin, oui, un DTO est mutable, c'est une des différences avec le VO. Une autre, c'est que tu ne le check pas (test pour savoir si c'est bien un INT etc). Enfin (toujours selon moi), il ne possède pas d'autre méthode que constructor, getter & setter.