## 定义
        一个对象池包含一组已经初始化并且可以使用的对象，可以在有需求时创建和销毁对象。
        对象池的用户可以从池子中取得对象，对其进行操作处理，并在不需要时归还给池子而非直接销毁。


## 设计的原则和思想
1. 解耦了对象的创建和使用。
2. 不变部分是使用，变化部分是创建。
3. 核心思想是对象复用(一个对象只能被一个对象引用)，节省时间。

## 一句话概括设计模式
    单例 + 享元 = 对象池

## 结构中包含的角色
1. 对象池（ObjectPool）
2. 对象池的对象（PooledObject）

## 最小可表达代码
    // 对象池的对象
    class PooledObject
    {
        private $id;

        public function __construct($id)
        {
            $this->id = $id;
        }

        public function getId()
        {
            return $this->id;
        }
    }

    // 对象池
    class ObjectPool
    {
        private static $resources = [];

        public static function add(PooledObject $resource)
        {
            self::$resources[$resource->getId()] = $resource;
        }

        public static function get($id)
        {
            return self::$resources[$id] ?? null;
        }
    }

    // 打印
    $id = 1;
    ObjectPool::add(new PooledObject($id));
    var_dump(ObjectPool::get($id)->getId(), ObjectPool::get($id)->getId());

## 优点
1. 复用池中对象，
2. 节省创建对象所需要的资源。
3. 不必重复初始化对象状态， 

## 缺点
1. 并发环境中,因为锁竞争而产生阻塞,这种开销要比创建销毁对象的开销高非常多。
2. 设计一个好的对象池的难度高。

## 何时使用
1. 频繁创建、销毁对象并且对象创建、销毁开销很大的场景
2. 资源(内存，CPU，网络等)受限的场景。

## 实际应用场景
1. 数据库连接池
2. 任务队列池
3. 游戏开发的游戏物体。
4. 管理内存。预先申请一片连续的内存空间作为对象池。
