获取对象的key_【PHP设计模式】对象池

前言

对象池(也称为资源池)被用来管理对象缓存。对象池是一组已经初始化过且可以直接使用的对象集合,用户在使用对象时可以从对象池中获取对象,对其进行操作处理,并在不需要时归还给对象池而非销毁它。

若对象初始化、实例化的代价高,且需要经常实例化,但每次实例化的数量较少的情况下,使用对象池可以获得显著的性能提升。常见的使用对象池模式的技术包括线程池、数据库连接池、任务队列池、图片资源对象池等。

当然,如果要实例化的对象较小,不需要多少资源开销,就没有必要使用对象池模式了,这非但不会提升性能,反而浪费内存空间,甚至降低性能。

对象池模式

<?php

/**
 * 数据库操作
 */
class Mysql 
{ 
    /**
     * 查询
     * 
     * @access public 
     */
    public function select ()
    { 
        echo '这是一个查询<br>';
    }
}

/**
 * 定义对象池
 */
class ObjectPool
{ 
    /**
     * 空闲连接池
     * 
     * @var array 
     */
    private $freePools = [];

    /**
     * 工作连接池
     * 
     * @var array 
     */
    private $workPools = [];

    /**
     * 最大连接池数量
     * 
     * @var int
     */
    private $maxPoolNum = 3;

    /**
     * 连接池现有数量
     * 
     * @var int
     */
    private $nowPoolNum = 0;

    /**
     * 从池子获取对象
     * 
     * @access public 
     * @param int $num 连接编号,用来学习时,方便观察
     * @return Mysql|bool
     */
    public function getPool ($num = 0) 
    { 
        if ($this->nowPoolNum === 0 || ($this->nowPoolNum < $this->maxPoolNum && count($this->freePools) === 0)) { 

            // 池子没有连接,或者连接池未满,新建连接
            $worker = new Mysql;

            // 将连接追加进工作连接池中
            $this->workPools[spl_object_hash($worker)] = $worker;

            // 已有连接数量+1
            $this->nowPoolNum++;

        } else if (count($this->freePools) > 0) {

            // 从空闲连接池中获取一个连接
            $worker = array_pop($this->freePools);

            // 将连接追加进工作连接池中
            $this->workPools[spl_object_hash($worker)] = $worker;

        } else { 
            echo '!!!!!没有空闲的连接,连接 ' . $num . ' 获取失败,请稍后再试!!!!!<br>';
            return false;
        }

        echo '获取连接 ' . $num . ' 成功<br>';

        return $worker;
    }

    /**
     * 释放工作中的数组
     * 
     * @access public 
     * @param string $key 数组键值
     * @return bool
     */
    public function releasePool ($worker, $num)
    { 
        // 加密对象,获取key值
        $key = spl_object_hash($worker);

        // 判断是否存在
        if (isset($this->workPools[$key])) { 

            // 释放数据
            unset($this->workPools[$key]);

            // 将对象放回空闲连接池
            $this->freePools[spl_object_hash($worker)] = $worker;

            return true;
        }

        return false;
    }
}

/**
 * 定义测试类
 */
class TestPool 
{ 
    /**
     * 使用数据库操作
     * 
     * @access public 
     * @return void
     */
    public function test () 
    { 
        // 实例化对象池
        $objectPool = new ObjectPool;

        // 获取连接
        $worker1 = $objectPool->getPool(1);
        $worker2 = $objectPool->getPool(2);
        $worker3 = $objectPool->getPool(3);
        $worker4 = $objectPool->getPool(4);

        // 释放连接
        if ($objectPool->releasePool($worker3, 3)) { 
            echo '释放连接 3 成功<br>';
        } else { 
            echo '释放连接 3 失败<br>';
        }
        
        // 重新获取连接4
        $worker4 = $objectPool->getPool(4);
    }
}

$test = new TestPool;

$test->test();

我们来看看测试结果:

f477c4d9a9095647b1ccac7180a1f8e1.png

从这里我们可以看出,前面三个成功获取连接,第四个由于没有空闲的连接,所以获取失败,后面释放了连接3之后,连接4又可以重新获取了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值