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
{
    // ...
}
scalar.php

Dabei geht aber schnell was schief, weil zusammengehörige Information durch voneinander unabhängige Variablen repräsentiert wird. Wir könnten viel zu leicht etwas durcheinander bringen:

<?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);
}
confusion.php

PHP unterstützt keine vom Entwickler definierten Datenstrukturen. Wir könnten die beiden Variablen 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'
];
array.php

Nun müssten wir allerdings - zumindest dann, wenn wir sauber arbeiten wollen - bei jedem Zugriff prüfen, ob der entsprechende Schlüssel im Array überhaupt existiert, da wir ansonsten einen Hinweis produzieren und eher unerwartet mit einem Nullwert weiterarbeiten.

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: beide Variablen in einem Objekt zusammenfassen.