PHP
Pattern: State
16.07.2021
236

Pattern: State

abstract class StateVehicle
{
    protected $vehicle;

    public function __construct(Vehicle $vehicle)
    {
        $this->vehicle = $vehicle;
    }

    abstract public function approve();
    abstract public function deny();

    public function onEnterState($previousState)
    {
    }
}

class StateVehicleCheck extends StateVehicle
{
    public function __construct(Vehicle $vehicle)
    {
        parent::__construct($vehicle);
    }

    public function approve()
    {
        $this->vehicle->setState(new StateVehicleFuelEnough($this->vehicle));
    }

    public function deny()
    {
        $this->vehicle->setState(new StateVehicleFuelNeedToRefuel($this->vehicle));
    }

    public function onEnterState($previousState)
    {
        if ($this->vehicle->getFuelLiters() > 30) {
            $this->approve();
        } else {
            $this->deny();
        }
    }
}

class StateVehicleFuelEnough extends StateVehicle
{
    public function __construct(Vehicle $vehicle)
    {
        parent::__construct($vehicle);
    }

    public function approve()
    {
        $this->vehicle->setState(new StateVehicleReady($this->vehicle));
    }

    public function deny()
    {
        $this->vehicle->setState(new StateVehicleWaitPassengers($this->vehicle));
    }

    public function onEnterState($previousState)
    {
        if ($this->vehicle->getPassengersCount() >= 10) {
            $this->approve();
        } else {
            $this->deny();
        }
    }
}

class StateVehicleFuelNeedToRefuel extends StateVehicle
{
    public function __construct(Vehicle $vehicle)
    {
        parent::__construct($vehicle);
    }

    public function approve()
    {
        throw new Exception('Not supported');
    }

    public function deny()
    {
        throw new Exception('Not supported');
    }

    public function onEnterState($previousState)
    {
        $this->vehicle->gotToGasStation();
    }
}

class StateVehicleWaitPassengers extends StateVehicle
{
    public function __construct(Vehicle $vehicle)
    {
        parent::__construct($vehicle);
    }

    public function approve()
    {
        throw new Exception('Not supported');
    }

    public function deny()
    {
        throw new Exception('Not supported');
    }

    public function onEnterState($previousState)
    {
        $this->vehicle->waitPassengers();
    }
}

class StateVehicleReady extends StateVehicle
{
    public function __construct(Vehicle $vehicle)
    {
        parent::__construct($vehicle);
    }

    public function approve()
    {
        throw new Exception('Not supported');
    }

    public function deny()
    {
        throw new Exception('Not supported');
    }

    public function onEnterState($previousState)
    {
        $this->vehicle->go();
    }
}

//
abstract class Vehicle
{
    private $state;

    public abstract function getFuelLiters();
    public abstract function getPassengersCount();

    public function getState(): StateVehicle
    {
        return $this->state;
    }

    public function setState(StateVehicle $state)
    {
        $previousState = $this->state;
        $this->state = $state;
        $this->state->onEnterState($previousState);
    }

    public function go()
    {
        echo 'Go.';
    }

    public function waitPassengers()
    {
        echo 'Wait passengers.';
    }

    public function gotToGasStation()
    {
        echo 'Got to gas station.';
    }
}

class VehicleBus extends Vehicle
{
    private $fuelLiters;
    private $passengersCount;

    public function __construct(int $fuelLiters, int $passengersCount)
    {
        $this->fuelLiters = $fuelLiters;
        $this->passengersCount = $passengersCount;
        $this->setState(new StateVehicleCheck($this));
    }

    public function getFuelLiters()
    {
        return $this->fuelLiters;
    }

    public function getPassengersCount()
    {
        return $this->passengersCount;
    }
}

$bus = new VehicleBus(20, 10);
echo '<hr>';
$bus = new VehicleBus(60, 1);
echo '<hr>';
$bus = new VehicleBus(31, 30);
echo '<hr>';
Источник: ZetRider
PHP
Pattern: Decorator
01.12.2021
13
Pattern: Decorator

Когда использовать: дополнить, изменить, расширить поведение объекта.interface Response { /** * @return array */ public function dat...

Читать →
PHP
Pattern: Strategy
23.11.2021
33
Pattern: Strategy

Когда использовать:  условия контекста могут менять реализацию интерфейса.interface Strategy { /** * @param string $message * @retu...

Читать →
PHP
Pattern: Factory method
11.11.2021
61
Pattern: Factory method

Когда использовать: возможно использование нескольких вариантов для выполнения операции, наследующих родительское поведение, реализующие поставленную...

Читать →