Value Object
Oft haben wir es beim Programmieren mit zwei oder mehr Informationen zu tun, die eng zusammengehören. Beispiele dafür sind 8 Meter, 3 Liter, 4 Kilogramm oder 12,50 Euro. Natürlich könnten wir solche Werte jeweils mit einzelnen skalaren Variablen repräsentieren:
<?php declare(strict_types=1);
namespace spriebsch\tfd\designPatterns\valueObject;
$amount = 200;
$currency = 'EUR';
do_something($amount, $currency);
function do_something(int $amount, string $currency): void
{
// ...
}
Dabei geht aber schnell was schief, weil wir zusammengehörige Information durch voneinander unabhängige Variablen repräsentieren.
<?php declare(strict_types=1);
namespace spriebsch\tfd\designPatterns\valueObject;
$amount1 = 100;
$currency1 = 'EUR';
$amount2 = 200;
$currency2 = 'GBP';
do_something($amount1, $currency2);
function do_something(int $amount, string $currency): void
{
var_dump($amount, $currency);
}
So leicht können wir Unsinn produzieren:
confusion.php:15: int(100) confusion.php:15: string(3) "GBP"
Welche Alternativen gibt es? PHP unterstützt keine vom Entwickler definierten Datenstrukturen. Wir könnten die beiden Variablen allenfalls in einem assoziativen Array zusammenfassen. Das würde etwa so aussehen:
<?php declare(strict_types=1);
namespace spriebsch\tfd\designPatterns\valueObject;
$money = [
'amount' => 200,
'currency' => 'EUR'
];
Nun müssen wir bei jedem Zugriff prüfen, ob der entsprechende Schlüssel im Array überhaupt existiert. Sonst produzieren wir einen Hinweis und arbeiten unerwartet mit einem Nullwert weiter. Das ist auch nicht wirklich schön und kann schnell zur Fehlerquelle werden.
Noch schlimmer aber ist, dass jeder alle Werte jederzeit nicht nur lesen, sondern auch schreiben und damit verändern kann. Das ist ja fast so schlimm wie das Problem mit den globalen Variablen: Es gerät viel zu schnell außer Kontrolle.
Die Lösung: wir fassen beide Variablen in einem Objekt zusammen.