PHP 對(duì)象池模式

2022-05-05 11:24 更新

什么是對(duì)象池

對(duì)象池設(shè)計(jì)模式 是一種創(chuàng)建型設(shè)計(jì)模式。它使用一組提前已準(zhǔn)備完成可以使用的對(duì)象,而不是根據(jù)需要分配或銷毀。這種來源被稱為:“池”(pool)。池的使用者將從池中請求一個(gè)對(duì)象,并對(duì)返回的對(duì)象進(jìn)行操作。在客戶端處理完成后,它將返回一種特定類型的工廠對(duì)象。返回給池,而不是銷毀。

對(duì)象池模式在一些情景下可以帶來明顯的性能提升。如:類實(shí)例初始化成本較高、類的實(shí)例化率較高、或類實(shí)例同時(shí)使用率不高的情況下。當(dāng)創(chuàng)建新對(duì)象(尤其是通過網(wǎng)絡(luò))的時(shí)間花費(fèi)不確定時(shí),池對(duì)象的獲得時(shí)間卻是可預(yù)測的。

這些優(yōu)點(diǎn)對(duì)于時(shí)間要求敏感的對(duì)象來說,是非常有用的。例如:數(shù)據(jù)庫連接、套接字連接、線程和大型圖形對(duì)象(如字體或位圖)。但在某些情況下,簡單的對(duì)象池(不包含外部資源,只占用內(nèi)存)可能效率不高,并且會(huì)降低性能。

1.4.2. UML 圖

Alt Pool UML Diagram

1.4.3. 代碼

WorkerPool.php

<?php

declare(strict_types=1);

namespace DesignPatterns\Creational\Pool;

use Countable;

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

    /**
     * @var StringReverseWorker[]
     */
    private array $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 count(): int
    {
        return count($this->occupiedWorkers) + count($this->freeWorkers);
    }
}

StringReverseWorker.php

<?php

declare(strict_types=1);

namespace DesignPatterns\Creational\Pool;

use DateTime;

class StringReverseWorker
{
    public function __construct()
    {
    }

    public function run(string $text): string
    {
        return strrev($text);
    }
}

 測試

Tests/PoolTest.php

<?php

declare(strict_types=1);

namespace DesignPatterns\Creational\Pool\Tests;

use DesignPatterns\Creational\Pool\WorkerPool;
use PHPUnit\Framework\TestCase;

class PoolTest extends TestCase
{
    public function testCanGetNewInstancesWithGet()
    {
        $pool = new WorkerPool();
        $worker1 = $pool->get();
        $worker2 = $pool->get();

        $this->assertCount(2, $pool);
        $this->assertNotSame($worker1, $worker2);
    }

    public function testCanGetSameInstanceTwiceWhenDisposingItFirst()
    {
        $pool = new WorkerPool();
        $worker1 = $pool->get();
        $pool->dispose($worker1);
        $worker2 = $pool->get();

        $this->assertCount(1, $pool);
        $this->assertSame($worker1, $worker2);
    }
}
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)