<?php
// https://dev.to/ianrodrigues/writing-value-objects-in-php-4acg
<?php declare(strict_types=1);
final class Price
{
const USD = 'USD';
const CAD = 'CAD';
/** @var float */
private $amount;
/** @var string */
private $currency;
public function __construct(float $amount, string $currency = 'USD')
{
if ($amount < 0) {
throw new \InvalidArgumentException("Amount should be a positive value: {$amount}.");
}
if (!in_array($currency, $this->getAvailableCurrencies())) {
throw new \InvalidArgumentException("Currency should be a valid one: {$currency}.");
}
$this->amount = $amount;
$this->currency = $currency;
}
private function getAvailableCurrencies(): array
{
return [self::USD, self::CAD];
}
public function getAmount(): float
{
return $this->amount;
}
public function getCurrency(): string
{
return $this->currency;
}
}
final class Price
{
// ...
private function hasSameCurrency(Price $price): bool
{
return $this->currency === $price->currency;
}
public function sum(Price $price): self
{
if (!$this->hasSameCurrency($price)) {
throw \InvalidArgumentException(
"You can only sum values with the same currency: {$this->currency} !== {$price->currency}."
);
}
return new self($this->amount + $price->amount, $this->currency);
}
final class Price
{
// ...
public function isEqualsTo(Price $price): bool
{
return $this->amount === $price->amount && $this->currency === $price->currency;
}
}
final class Price
{
// ...
private function hash(): string
{
return md5("{$this->amount}{$this->currency}");
}
public function isEqualsTo(Price $price): bool
{
return $this->hash() === $price->hash();
}
}
final class Price
{
// ...
public function __construct(float $amount, string $currency = 'USD')
{
if ($amount < 0) {
throw new \InvalidArgumentException("Amount should be a positive value: {$amount}.");
}
if (!in_array($currency, $this->getAvailableCurrencies())) {
throw new \InvalidArgumentException("Currency should be a valid one: {$currency}.");
}
$this->amount = $amount;
$this->currency = $currency;
}
}