PHP设计模式之对象池模式
关于对象池
传统的php开发模式基本用不到对象池的,当请求完毕时,我们自己创建的所有对象等都会自动销魂。但是,如果常驻内存运行的开发模式,比如使用了swoole,那么使用对象池模式是非常有用的。
对象池模式是一种提前准备了一组已经初始化了的对象『池』而不是按需创建或者销毁的创建型设计模式。对象池的客户端会向对象池中请求一个对象,然后使用这个返回的对象执行相关操作。当客户端使用完毕,它将把这个特定类型的工厂对象返回给对象池,而不是销毁掉这个对象。
在初始化实例成本高,实例化率高,可用实例不足的情况下,对象池可以极大地提升性能。在创建对象(尤其是通过网络)时间花销不确定的情况下,通过对象池在可期时间内就可以获得所需的对象。
无论如何,对象池模式在需要耗时创建对象方面,例如创建数据库连接,套接字连接,线程和大型图形对象(比方字体或位图等),使用起来都是大有裨益的。在某些情况下,简单的对象池(无外部资源,只占内存)可能效率不高,甚至会有损性能。
实现
首先,我们需定义三个方法,分别如下:
get
方法获取连接(连接池未满时会创建新的连接)put
方法回收连接fill
方法填充连接池(提前创建连接)
class Obj
{
private $rand;
public function __construct()
{
$this->rand = mt_rand(10000, 99999);
}
public function getTime ()
{
return $this->rand;
}
}
class ObjPool
{
private $freePools = [];
private $usedPools = [];
public function fill()
{
for ($i = 0; $i < 100; $i ++) {
$obj = new Obj();
$this->freePools[spl_object_hash($obj)] = $obj;
}
}
public function get () : Obj
{
if (!count($this->freePools)) {
throw new \Exception('pool empty');
}
$obj = array_pop($this->freePools);
$this->usedPools[spl_object_hash($obj)] = $obj;
return $obj;
}
public function put (Obj $obj)
{
$hashId = spl_object_hash($obj);
if (isset($this->usedPools[$hashId])) {
unset($this->usedPools[$hashId]);
$this->freePools[$hashId] = $obj;
}
}
public function __get ($name)
{
return $this->$name ?? null;
}
}
文章部分内容参考自:https://learnku.com/docs/php-design-patterns/2018/Pool/1491