in design pattern php object oriented programming oop cleanc code programming ~ read.

State Pattern in PHP

In this post we are going to talk about State Pattern in Object Oriented Programming.

What is State Pattern?

You must remember that within a class you have some if statements for different states of the class in order to perform different logics? Oh well State Pattern is a pattern that extract the state of your class into a seperate class. Per state per class.

And it also follows Open Close Principle that the class itself is closed for changes while the state are open for changing.

Without State Pattern

Let's look at an example without using State Pattern.

<?php

class Worker {

    private $working = 1;
    private $meeting = 2;
    private $sick = 3;
    private $lunch = 4;    
    private $general = 5;
    private $leave = 6;
    private $state = $this->working;

    public function __construct() {}

    public function showState() {
        if ($this->state == $this->working) {
            echo 'The worker is working';
        } else if ($this->state == $this->meeting) {
            echo 'The worker is having a meeting';
        } else if ($this->state == $this->sick) {
            echo 'The worker is sick';
        } else if ($this->state == $this->lunch) {
            echo 'The worker is having lunch';
        } else if ($this->state == $this->general) {
            echo 'The worker is doing something';
        } else if ($this->state == $this->leave) {
            echo 'The worker is gone';
        }
    }
}

With State Pattern

Next let's use State Design Pattern to extract all of states into classes.

First let's create an abstract class named State.

<?php

abstract class State {  
    public function handleRequest() {
        echo 'this needed to be overriden by sub classes'
    }
}

(State.php)

Next we are going to convert the state properties into state classes that we are going to create soon.

<?php

class Worker {

    private $working;
    private $meeting;
    private $sick;
    private $lunch;
    private $general;
    private $leave;
    private $state;

    public function __construct() {
        $this->working = new WorkingState($this);
    }

    public function showState() {
        if ($this->state == $this->working) {
            echo 'The worker is working';
        } else if ($this->state == $this->meeting) {
            echo 'The worker is having a meeting';
        } else if ($this->state == $this->sick) {
            echo 'The worker is sick';
        } else if ($this->state == $this->lunch) {
            echo 'The worker is having lunch';
        } else if ($this->state == $this->general) {
            echo 'The worker is doing something';
        } else if ($this->state == $this->leave) {
            echo 'The worker is gone';
        }
    }
}

Next let's create the WorkingState class.

<?php

class WorkingState extends State {  
    private $worker;

    public function __construct(Worker $woker) {
        $this->worker = $woker;
    }

    public function handleRequest() {
        echo 'Changing state to working';
        $this->worker->setState($this->worker->getWorkingState());
    }
}

(WorkingState.php)

Next let's create the related methods within out Worker class.

<?php

class Worker {

    private $working;
    private $meeting;
    private $sick;
    private $lunch;
    private $general;
    private $leave;
    private $state;

    public function __construct() {
        $this->working = new WorkerState($this);
    }

    public function showState() {
        $this->state->handleRequest();
    }

    public function setState(State $state) {
        $this->state = $state;
    }

    public function getWorkingState() {
        return $this->working
    }
}

(Worker.php)

As you can see that we remove the logic of deciding the state of our application into seperate classes. Let's finish up this Worker class.

<?php

class Worker {

    private $working;
    private $meeting;
    private $sick;
    private $lunch;
    private $general;
    private $leave;
    private $state;

    public function __construct() {
        $this->working = new WorkerState($this);
        $this->meeting = new MeetingState($this);
        $this->sick    = new SickState($this);
        $this->lunch   = new LunchState($this);
        $this->general = new GeneralState($this);
        $this->leave   = new LeaveState($this);
    }

    public function showState() {
        $this->state->handleRequest();
    }

    public function setState(State $state) {
        $this->state = $state;
    }

    public function getWorkingState() {
        return $this->working
    }
}

(Worker.php)

End

Hope this crash course is useful to you guys. State Design Pattern could be really helpful once you realise a class is handling too much of state itself.

And if you have any opinions or ideas please leave it below. Thanks and happy coding!

comments powered by Disqus