Object pool design pattern

Object pool design pattern – Learn design patterns

Object pool design pattern is concept which essentially propose reuse of existing objects, instead of creating lots of new ones.

Object pool design pattern belongs to the category of creational design patterns. Within this pattern category we have:

This pattern is used in a situations where creation of object is considered as “expensive operation”, i.e. initialization of objects takes lots of time.

Meaning, we can use pool design pattern when:

  • The cost of initialization of object is high
  • We are expecting high number of instances (lots of objects)
  • The number of objects that we use in time is low (limited)

The idea behind pool design pattern is simple:

  • We create a pool which has limited number of reusable objects.
  • Client asks for a reusable object from a pool.

You like reading about design patterns? Well that’s fantastic!

Subscribe to my newsletter and get notifications about new posts (1 email per week max, just to keep you in “the loop”).

Object Pool Design Pattern PHP Example

Firstly, we want to create Employee class.

Each employee will have id, personnelNumber, firstname and lastname.

Furthermore, each employee will have getters for parameters and getInfo() function which gives information about employee.

Finally, constructor of employee will have sleep(10) causing each object creation to take 10 seconds. This simulates expensive action, meaning we have to wait for some time before object is created.

This way, when we execute the example, we will clearly see which objects were already created in pool (we didn’t have to wait) and when there were no objects in pool (we had to wait 10 seconds to create a new object).

<?php

/**
 * Class Employee represents an entity class for a single employee.
 * This class will create objects that we can later use (either directly or in a pool).
 */
class Employee
{
    private $id;
    private $personnelNumber;
    private $firstname;
    private $lastname;

    /**
     * Employee constructor.
     *
     * @param $id
     * @param $personnelNumber
     * @param $firstname
     * @param $lastname
     */
    public function __construct($id, $personnelNumber, $firstname, $lastname)
    {
        $this->id = $id;
        $this->personnelNumber = $personnelNumber;
        $this->firstname = $firstname;
        $this->lastname = $lastname;

        echo "New employee '$this->firstname $this->lastname' is being created, we need to wait 10 seconds. \n";
        sleep(10);
    }

    public function getId()
    {
        return $this->id;
    }

    public function getFirstname()
    {
        return $this->firstname;
    }

    public function getLastname()
    {
        return $this->lastname;
    }

    public function getPersonnelNumber()
    {
        return $this->personnelNumber;
    }

    public function getInfo()
    {
        echo "$this->id : Employee $this->firstname $this->lastname has personnel number $this->personnelNumber \n";
    }
}

Then, we will implement EmployeePool class.

This class has array of $availableEmployees and array of $busyEmployees.

Furthermore, this class has getEmployee() function and release(Employee $employee) function.

First function provides employee, either by creating a new object, or providing an existing object, if there is one available. This function represents the core implementation of object pool pattern.

Release function simply releases object, making it available for future use.

<?php

/**
 * Class EmployeePool
 */
class EmployeePool
{
    private $busyEmployees;
    private $availableEmployees;

    private $personnelNumbers = [ 'A101', 'A102', 'A103', 'A104', ];
    private $firstnames = [ 'John', 'Johana', 'Milan', 'Milana', ];
    private $lastnames = [ 'Doe', 'Latinovic', 'Nickelson', ];

    /**
     * EmployeePool constructor.
     */
    public function __construct()
    {
        $this->busyEmployees = [];
        $this->availableEmployees = [];
    }

    /**
     * @return Employee|mixed
     */
    public function getEmployee()
    {
        if (0 === count($this->availableEmployees)) {
            echo "There are no available employees in pool, we need to create/hire one. \n";
            $id = count($this->availableEmployees) + count($this->busyEmployees) + 1;
            $personnelNumber = $this->personnelNumbers[array_rand($this->personnelNumbers, 1)];
            $firstname = $this->firstnames[array_rand($this->firstnames, 1)];
            $lastname = $this->lastnames[array_rand($this->lastnames, 1)];
            $employee = new Employee($id, $personnelNumber, $firstname, $lastname);
        }
        else {
            echo "There are available employees in pool, we will pick one of them. \n";
            $employee = array_pop($this->availableEmployees);
        }
        $this->busyEmployees[$employee->getId()] = $employee;

        return $employee;
    }

    /**
     * @param $employee
     */
    public function release($employee)
    {
        $id = $employee->getId();
        $firstname = $employee->getFirstname();
        $lastname = $employee->getLastname();

        if (isset($this->busyEmployees[$id])) {
            unset($this->busyEmployees[$id]);
            $this->availableEmployees[$id] = $employee;
        }

        echo "Employee $firstname $lastname has been released, meaning he is again available. \n";
    }

    /**
     *
     */
    public function getPoolStatus()
    {
        $numberOfAvailableEmployees = count($this->availableEmployees);
        $numberOfBusyEmployees = count($this->busyEmployees);

        echo "Pool has $numberOfAvailableEmployees available employees and $numberOfBusyEmployees busy employees. \n";
    }
}

Finally, we want to create Main.php class which represents a simple example where we want to use EmployeePool.

Concept is simple, we have job that needs to be done.

For that, we will hire several employees by asking EmployeePool to provide us with them. Then, when some of them are finished with work, we will release them.

However, we will have some more additional tasks to do, so we will ask EmployeePool for new employees again. But this time, EmployeePool will already have some employees (created objects but currently not in use) and we will get these objects.

<?php

require_once("Employee.php");
require_once("EmployeePool.php");

$pool = new EmployeePool();

$employee1 = $pool->getEmployee();
$pool->getPoolStatus();

$employee2 = $pool->getEmployee();
$pool->getPoolStatus();

$employee3 = $pool->getEmployee();
$pool->getPoolStatus();

$employee4 = $pool->getEmployee();
$pool->getPoolStatus();

$pool->release($employee2);
$pool->release($employee3);

$employee5 = $pool->getEmployee();
$pool->getPoolStatus();

$employee6 = $pool->getEmployee();
$pool->getPoolStatus();

$employee7 = $pool->getEmployee();
$pool->getPoolStatus();

//echo "Employee 1: " . $employee1->getInfo() . "\n";
//echo "Employee 2: " . $employee2->getInfo() . "\n";
//echo "List of occupied employees: " . $pool->getBusyEmployees() . "\n";
//echo "List of free employees: " . $pool->getAvailableEmployees() . "\n";

Finally, we will get this result in console.

There are no available employees in pool, we need to create/hire one.
New employee 'Milana Latinovic' is being created, we need to wait 10 seconds.
Pool has 0 available employees and 1 busy employees.

There are no available employees in pool, we need to create/hire one.
New employee 'Milana Nickelson' is being created, we need to wait 10 seconds.
Pool has 0 available employees and 2 busy employees.

There are no available employees in pool, we need to create/hire one.
New employee 'Johana Nickelson' is being created, we need to wait 10 seconds.
Pool has 0 available employees and 3 busy employees.

There are no available employees in pool, we need to create/hire one.
New employee 'Milana Nickelson' is being created, we need to wait 10 seconds.
Pool has 0 available employees and 4 busy employees.

Employee Milana Nickelson has been released, meaning he is again available.

Employee Johana Nickelson has been released, meaning he is again available.

There are available employees in pool, we will pick one of them.
Pool has 1 available employees and 3 busy employees.

There are available employees in pool, we will pick one of them.
Pool has 0 available employees and 4 busy employees.

There are no available employees in pool, we need to create/hire one.
New employee 'John Doe' is being created, we need to wait 10 seconds.
Pool has 0 available employees and 5 busy employees.

References