原文转自:https://learnku.com/docs/php-design-patterns/2018/Pool/1491


对象池模式是一种提前准备了一组已经初始化了的对象『池』而不是按需创建或者销毁的创建型设计模式。对象池的客户端会向对象池中请求一个对象,然后使用这个返回的对象执行相关操作。当客户端使用完毕,它将把这个特定类型的工厂对象返回给对象池,而不是销毁掉这个对象。

在初始化实例成本高,实例化率高,可用实例不足的情况下,对象池可以极大地提升性能。在创建对象(尤其是通过网络)时间花销不确定的情况下,通过对象池在可期时间内就可以获得所需的对象。

在swoole框架基本上都使用这个模式。

例如easyswoole文档中的说明

  • 用户A请求/Index,经过url解析以及路由转发,定位到了App\HttpController\Index.php
  • 控制器由于是第一次请求,new App\HttpController\Index.php,并将该对象存入到对象池中。
  • 对象池出列,获取该对象,并进行调用index方法进行处理请求
  • 处理完毕,将对象的属性重置为默认值,对象回收对象池
  • 用户B请求/Index,经过url解析以及路由转发,定位到了App\HttpController\Index.php
  • 控制器由于是二次请求,对象池直接获取到第一次的对象,不需要new,直接调用 index方法进行处理。

简单的对象池demo

StringReverseWorker.php

namespace App\Pool;



class StringReverseWorker
{
    /**
     * @var \DateTime
     */
    private $createdAt;

    public function __construct()
    {
        $this->createdAt = new \DateTime();
    }



    public function run(string $text, array $callback)
    {

        echo strrev($text);
        //把$this做为参数返回到调用此方法的对象里的回调方法
        call_user_func($callback, $this);
    }
}

WorkerPool.php


namespace App\Pool;


class WorkerPool implements \Countable
{
    /**
     * @var StringReverseWorker[]
     */
    private $occupiedWorkers = [];

    /**
     * @var StringReverseWorker[]
     */
    private $freeWorkers = [];

    public function get(): StringReverseWorker
    {
        if (count($this->freeWorkers) == 0) {
            $worker = new StringReverseWorker();
        } else {
            $worker = array_pop($this->freeWorkers);
        }

        $this->occupiedWorkers[spl_object_hash($worker)] = $worker;

        return $worker;
    }

    public function dispose(StringReverseWorker $worker)
    {
        $key = spl_object_hash($worker);

        if (isset($this->occupiedWorkers[$key])) {
            unset($this->occupiedWorkers[$key]);
            $this->freeWorkers[$key] = $worker;
        }
    }

    public function callback($responseObj)
    {
        var_dump($responseObj);
        echo "从调用类返回过来。";
    }
    public function test()
    {
        $worker =$this->get();
        //设置回调函数在run方法中完成逻辑并且返回到自己
        $worker->run('123<br/>',array($this,'callback'));
    }

    /**
     * 返回占用的对象数和空闲的对象数
     * @return int
     */
    public function count(): int
    {
        return count($this->occupiedWorkers) + count($this->freeWorkers);
    }
}

调用代码

require "Loader.php";
Loader::init();



use App\Pool\WorkerPool;

$pool = new WorkerPool();

$pool->test();

echo"<br/>";

echo Loader::getLoadFileNum();
Last modification:January 31, 2020
如果觉得我的文章对你有用,请随意赞赏