Skip to content

Instantly share code, notes, and snippets.

@csarrazi
Created November 14, 2012 15:38
Show Gist options
  • Save csarrazi/4072823 to your computer and use it in GitHub Desktop.
Save csarrazi/4072823 to your computer and use it in GitHub Desktop.
State pattern in PHP
<?php
abstract class AbstractState implements StateInterface
{
/**
* @var WorkflowInterface
*/
private $workflow;
public function __construct(WorkflowInterface $workflow)
{
$this->workflow = $workflow;
}
public function methodA()
{
throw new \Exception('You should not call that method in that state');
}
public function methodB()
{
throw new \Exception('You should not call that method in that state');
}
}
<?php
abstract class AbstractWorkflow
{
/**
* @var StateInterface
*/
private $state;
public function setState(StateInterface $state)
{
$this->state = $state;
}
}
<?php
class AState extends AbstractState implements StateInterface
{
public function methodA()
{
try {
// Do stuff
// ...
} catch (\Exception $e) {
$this->workflow->setState(new ErrorState($this->workflow, $this));
return $this->workflow;
}
$this->workflow->setState(new BState($this->workflow));
return $this->workflow;
}
}
<?php
class BState extends AbstractState implements StateInterface
{
public function methodB()
{
try {
// Do stuff
// ...
} catch (\Exception $e) {
$this->workflow->setState(new ErrorState($this->workflow, $this));
return $this->workflow;
}
$this->workflow->setState(new EndState($this->workflow));
return $this->workflow;
}
}
<?php
class EndState extends AbstractState implements StateInterface
{
}
<?php
class ErrorState extends AbstractState implements StateInterface
{
/**
* @var StateInterface
*/
private $previousState;
public function __construct(WorkflowInterface $workflow, StateInterface $previousState = null)
{
parent::__construct($workflow);
$this->previousState = $previousState;
}
}
<?php
$workflow = new MyWorkflow();
$workflow->methodA(); // Switches from state A to state B
$workflow->methodB(); // Switches from state B to EndState
$workflow = new MyWorkflow();
$workflow->methodB(); // Switches from state A to Error state
$workflow = new MyWorkflow();
$workflow->methodA(); // Switches from state A to state B
$workflow->methodB(); // Switches from state B to Error state
<?php
class MyWorkflow extends AbstractWorkflow implements WorkflowInterface
{
public function __construct()
{
$this->state = new AState($this);
}
public function methodA()
{
return $this->state->methodA();
}
public function methodB()
{
return $this->state->methodB();
}
}
<?php
interface StateInterface
{
public function methodA();
public function methodB();
}
<?php
interface WorkflowInterface
{
public function setState(StateInterface $state);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment