<?php
interface ICupboard {
public function getNextCup(): Cup;
public function haveCups(): bool;
}
class InfiniteCupBoard implements ICupboard {
public function getNextCup(): Cup {
return Cup::createEmpty();
}
public function haveCups(): bool {
return true;
}
}
interface ITap {
public function getWater(): Liquid;
}
class InfiniteTap implements ITap {
private int $waterVolumePerReuqest;
public function __construct(int $waterVolumePerReuqest) {
$this->waterVolumePerReuqest = $waterVolumePerReuqest;
}
public function getWater(): Liquid {
return Liquid::createVolume($this->waterVolumePerReuqest);
}
}
class Cup {
private Liquid $liquid;
private int $volume;
private function __construct(Liquid $liquid, int $volume = 300) {
$this->liquid = $liquid;
$this->volume = $volume;
}
public static function createEmpty(): self {
return new self(Liquid::createEmpty());
}
public function fill(Liquid $liquid): void {
if (false === $this->canAddLiquid($liquid)) {
throw new DomainException(
sprintf(
'Cannot hold liquid volume. Expected volume: %s. Current volume: %s. Provided volume: %s.',
$this->volume,
$this->liquid->getVolume(),
$liquid->getVolume()
)
);
}
$this->liquid = $this->liquid->add($liquid);
}
public function canAddLiquid(Liquid $liquid): bool {
return $this->volume >= $this->liquid->getVolume() + $liquid->getVolume();
}
}
class Liquid {
private int $volume;
private function __construct(int $volume) {
$this->volume = $volume;
}
public static function createEmpty(): self {
return new self(0);
}
public static function createVolume(int $volume): self {
return new self($volume);
}
public function add(Liquid $liquid): self {
return new self($this->volume + $liquid->volume);
}
public function getVolume(): int {
return $this->volume;
}
}
class FillCupsWithWater {
private ITap $tap;
private ICupboard $cupboard;
public function __construct(ITap $tap, ICupboard $cupboard) {
$this->tap = $tap;
$this->cupboard = $cupboard;
}
public function __invoke(int $cupsToFillCount): array {
$filledCups = [];
while($this->cupboard->haveCups() && $cupsToFillCount) {
$cup = $this->cupboard->getNextCup();
$water = $this->tap->getWater();
while($cup->canAddLiquid($water)) {
$cup->fill($water);
}
$filledCups[] = $cup;
$cupsToFillCount--;
}
return $filledCups;
}
}
$fillCupsWithWater = new FillCupsWithWater(new InfiniteTap(14), new InfiniteCupBoard);
print_r($fillCupsWithWater(4));
Warning: PHP Startup: Unable to load dynamic library 'sodium.so' (tried: /usr/lib/php/8.3.5/modules/sodium.so (libsodium.so.23: cannot open shared object file: No such file or directory), /usr/lib/php/8.3.5/modules/sodium.so.so (/usr/lib/php/8.3.5/modules/sodium.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0
Array
(
[0] => Cup Object
(
[liquid:Cup:private] => Liquid Object
(
[volume:Liquid:private] => 294
)
[volume:Cup:private] => 300
)
[1] => Cup Object
(
[liquid:Cup:private] => Liquid Object
(
[volume:Liquid:private] => 294
)
[volume:Cup:private] => 300
)
[2] => Cup Object
(
[liquid:Cup:private] => Liquid Object
(
[volume:Liquid:private] => 294
)
[volume:Cup:private] => 300
)
[3] => Cup Object
(
[liquid:Cup:private] => Liquid Object
(
[volume:Liquid:private] => 294
)
[volume:Cup:private] => 300
)
)
Output for 7.3.13 - 7.3.33
Parse error: syntax error, unexpected 'int' (T_STRING), expecting function (T_FUNCTION) or const (T_CONST) in /in/AD5bt on line 24
Process exited with code 255.