States
Implement the pattern State in yours projects.
Library to create classes following the State pattern in PHP. This can be a cleaner way for an object to change its behavior at runtime without resorting to large monolithic conditional statements and this improve maintainability.
The state pattern is a behavioral software design pattern that implements a state machine in an object-oriented way. With the state pattern, a state machine is implemented by implementing each individual state as a derived class of the state pattern interface, and implementing state transitions by invoking methods defined by the pattern's superclass.
The state pattern can be interpreted as a strategy pattern which is able to switch the current strategy through invocations of methods defined in the pattern's interface.
This pattern is used in computer programming to encapsulate varying behavior for the same object based on its internal state. This can be a cleaner way for an object to change its behavior at runtime without resorting to large monolithic conditional statements and this improve maintainability.
Features
Create several states
Split classes in states to avoid understandable large monolithic statements.
Inherit states and classes
Complete and factorize states thank to inheritance. Stated classes can be also inherited.
Automate states switching
Define states switching rules based on object's properties.
Implement every where
Thanks to traits and interfaces, use this pattern on your existent code. Compatible with Doctrine.
Fork the project on GitHub
It is open source! Hosted, developed, and maintained on GitHub.
View GitHub Project
Support this project on Patreon
This project is free and will remain free, but its development is not. If you like it and help us maintain it and evolve it, don't hesitate to support us on Patreon.
Support it
Example
<?php
declare(strict_types=1);
namespace Acme;
require_once 'vendor/autoload.php';
use Closure;
use DateTime;
use Teknoo\States\Automated\AutomatedInterface;
use Teknoo\States\Automated\AutomatedTrait;
use Teknoo\States\Automated\Assertion\Property;
use Teknoo\States\Automated\Assertion\Property\IsEqual;
use Teknoo\States\Proxy\ProxyInterface;
use Teknoo\States\Proxy\ProxyTrait;
use Teknoo\States\State\AbstractState;
class English extends AbstractState
{
public function sayHello(): Closure
{
return function(): string {
return 'Good morning, '.$this->name;
};
}
public function displayDate(): Closure
{
return function(DateTime $now): string {
return $now->format('m d, Y');
};
}
}
class French extends AbstractState
{
public function sayHello(): Closure
{
return function(): string {
return 'Bonjour, '.$this->name;
};
}
public function displayDate(): Closure
{
return function(DateTime $now): string {
return $now->format('d m Y');
};
}
}
class Person implements ProxyInterface, AutomatedInterface
{
use ProxyTrait;
use AutomatedTrait;
private string $name;
private string $country;
public function __construct()
{
$this->initializeStateProxy();
}
protected static function statesListDeclaration(): array
{
return [
English::class,
French::class
];
}
protected function listAssertions(): array
{
return [
(new Property([English::class]))
->with('country', new IsEqual('en')),
(new Property([French::class]))
->with('country', new IsEqual('fr')),
];
}
public function setName(string $name): Person
{
$this->name = $name;
return $this;
}
public function setCountry(string $country): Person
{
$this->country = $country;
$this->updateStates();
return $this;
}
}
$frenchMan = new Person();
$frenchMan->setCountry('fr');
$frenchMan->setName('Roger');
$englishMan = new Person();
$englishMan->setCountry('en');
$englishMan->setName('Richard');
$now = new DateTime('2016-07-01');
foreach ([$frenchMan, $englishMan] as $man) {
echo $man->sayHello().PHP_EOL;
echo 'Date: '.$man->displayDate($now).PHP_EOL;
}
//Display
//Bonjour, Roger
//Date: 01 07 2016
//Good morning, Richard
//Date: 07 01, 2016