Währungen prüfen

Wir wollen in der Lage sein, Geldbeträge zu addieren. Dabei müssen wir sicherstellen, dass wir nicht unterschiedliche Währungen addieren:

<?php declare(strict_types=1);

namespace spriebsch\tfd\designPatterns\valueObject\money\add;

class Money
{
    public function __construct(
        private int $amount,
        private Currency $currency
    ) {}

    public function add(self $that): self
    {
        $this->ensureSameCurrency($that);

        return new self($this->amount + $that->amount, $this->currency);
    }

    private function ensureSameCurrency(self $that): void
    {
        if ($this->currency !== $that->currency) {
            throw new MoneyException('Currency mismatch');
        };
    }
}
Money.php
<?php declare(strict_types=1);

namespace spriebsch\tfd\designPatterns\valueObject\money\add;

require __DIR__ . '/autoload.php';

$money = new Money(200, Currency::EUR);
$sum = $money->add(new Money(100, Currency::EUR));

var_dump($sum);
example.php

Wenn wir gleiche Währungen addieren, geht alles gut:

example.php:10:
class spriebsch\tfd\designPatterns\valueObject\money\add\Money#5 (2) {
  private int $amount =>
  int(300)
  private spriebsch\tfd\designPatterns\valueObject\money\add\Currency $currency =>
  enum spriebsch\tfd\designPatterns\valueObject\money\add\Currency::EUR;
}
Ausgabe von example.php
example.php ausführen

Das Addieren von unterschiedlichen Währungen dagegen führt zu einer Exception:

<?php declare(strict_types=1);

namespace spriebsch\tfd\designPatterns\valueObject\money\add;

require __DIR__ . '/autoload.php';

$money = new Money(200, Currency::EUR);
$money->add(new Money(100, Currency::GBP));
example-will-fail.php
PHP Fatal error:  Uncaught spriebsch\tfd\designPatterns\valueObject\money\add\MoneyException: Currency mismatch in Money.php:22
Stack trace:
#0 Money.php(14): spriebsch\tfd\designPatterns\valueObject\money\add\Money->ensureSameCurrency()
#1 example-will-fail.php(8): spriebsch\tfd\designPatterns\valueObject\money\add\Money->add()
#2 {main}
  thrown in Money.php on line 22
Ausgabe von example-will-fail.php
example-will-fail.php ausführen

Wertobjekte haben normalerweise eine equals()-Methode, mit der sie vergleichen werden können.