Ein Bankkonto mit Geschäftsregeln

<?php declare(strict_types=1);

namespace spriebsch\tfd\softwareArchitecture\eventBased\eventSourcing\enforcingAccount;

use RuntimeException;

final class Account
{
    public function __construct(
        private readonly AccountId $id,
        private readonly Currency $currency,
        private Money $balance
    ) {
        $this->ensureSameCurrency($balance);
        $this->ensureNotNegative($balance);
    }

    public function id(): AccountId
    {
        return $this->id;
    }

    public function setBalance(Money $balance): void
    {
        $this->ensureSameCurrency($balance);
        $this->ensureNotNegative($balance);

        $this->balance = $balance;
    }

    public function balance(): Money
    {
        return $this->balance;
    }

    public function currency(): Currency
    {
        return $this->currency;
    }

    private function ensureSameCurrency(Money $money): void
    {
        if ($this->currency !== $money->currency()) {
            throw new RuntimeException('Currency mismatch');
        };
    }

    private function ensureNotNegative(Money $money): void
    {
        if ($money->amountInCents() < 0) {
            throw new RuntimeException('Negative balance');
        }
    }
}
Account.php

Jetzt könnte es eine Geschäftsregel geben, dass der Kontostand nicht negativ werden darf. In der Realität ist das meist gar nicht wirklich so, denn beispielsweise Banken leben ja sehr gut davon, dass Konten ins Minus laufen. Aber nehmen wir einmal an, dass wir für unser Konto diese Regel haben wollen, weil unsere Kunden prepaid einkaufen und das nur tun dürfen, wenn das Konto ausreichend gedeckt ist.