美文网首页
设计模式(二):单例、多例、对象池模式

设计模式(二):单例、多例、对象池模式

作者: 何笙 | 来源:发表于2019-05-07 16:33 被阅读0次

    单例模式(Singleton Pattern)

    意图: 保证一个类仅有一个实例,并提供一个访问它的全局访问点。
    主要解决: 一个全局使用的类频繁地创建与销毁
    解决方法:构造函数是私有,不允许直接new实例化;判断是否已经有这个单例,如果有则返回,如果没有则创建。
    应用场景:I/O与数据库等连接

    示例代码:
    Singleton.php

    <?php 
    class Singleton {
    
        private static $instance = null;
    
        private function __construct() {}
    
        private function __clone() {}
    
        //防止被反序列化
        private function __wakeup() {}
    
        public static function getInstance() {
            if (is_null(self::$instance)) {
                self::$instance = new Singleton();
            }
            return self::$instance;
        }
    }
    
    $instance = Singleton::getInstance();
    

    多例模式(Muliton)

    多例模式和单例模式类似,但可以返回多个实例。

    示例代码:
    Multition.php

    <?php
    class Multition {
    
        private static $instances = array();
    
        const INSTANCE = array('instance1',  'instance2');
    
        private function __construct() {}
    
        private function __clone() {}
    
        //防止被反序列化
        private function __wakeup() {}
    
        public static function getInstance($instanceName) {
            if (!in_array($instanceName, self::INSTANCE)) {
                throw new Exception('error');
            }
            if (!array_key_exists($instanceName, self::$instances)) {
                self::$instances[$instanceName] = new self();
            }
    
            return self::$instances[$instanceName];
        }
    }
    

    对象池模式(Pool)

    对象池模式是多例模式的一个变种,对象池是一组已经初始化过且可以直接使用的对象集合,用户在使用对象时可以从对象池中获取对象,对其进行操作处理,并在不需要时归还给对象池而非销毁它。
    若对象初始化、实例化的代价高,且需要经常实例化,但每次实例化的数量较少的情况下,使用对象池可以获得显著的性能提升。如果要实例化的对象较小,不需要多少资源开销,就没有必要使用对象池模式了,这非但不会提升性能,反而浪费内存空间,甚至降低性能。
    常见的使用对象池模式的技术包括线程池、数据库连接池、任务队列池、图片资源对象池等。

    示例代码:
    Pool.php

    <?php
    
    namespace DesignPatterns\Creational\Pool;
    
    class Pool
    {
    
        private $instances = array();
        private $class;
    
        public function __construct($class)
        {
            $this->class = $class;
        }
    
        public function get()
        {
            if (count($this->instances) > 0) {
                return array_pop($this->instances);
            }
    
            return new $this->class();
        }
    
        public function dispose($instance)
        {
            $this->instances[] = $instance;
        }
    }
    

    Processor.php

    <?php
    
    namespace DesignPatterns\Creational\Pool;
    
    class Processor
    {
    
        private $pool;
        private $processing = 0;
        private $maxProcesses = 3;
        private $waitingQueue = [];
    
        public function __construct(Pool $pool)
        {
            $this->pool = $pool;
        }
    
        public function process($image)
        {
            if ($this->processing++ < $this->maxProcesses) {
                $this->createWorker($image);
            } else {
                $this->pushToWaitingQueue($image);
            }
        }
    
        private function createWorker($image)
        {
            $worker = $this->pool->get();
            $worker->run($image, array($this, 'processDone'));
        }
    
        public function processDone($worker)
        {
            $this->processing--;
            $this->pool->dispose($worker);
    
            if (count($this->waitingQueue) > 0) {
                $this->createWorker($this->popFromWaitingQueue());
            }
        }
    
        private function pushToWaitingQueue($image)
        {
            $this->waitingQueue[] = $image;
        }
    
        private function popFromWaitingQueue()
        {
            return array_pop($this->waitingQueue);
        }
    }
    

    Worker.php

    <?php
    
    namespace DesignPatterns\Creational\Pool;
    
    class Worker
    {
    
        public function __construct()
        {
            // let's say that constuctor does really expensive work...
            // for example creates "thread"
        }
    
        public function run($image, array $callback)
        {
            // do something with $image...
            // and when it's done, execute callback
            call_user_func($callback, $this);
        }
    }

    相关文章

      网友评论

          本文标题:设计模式(二):单例、多例、对象池模式

          本文链接:https://www.haomeiwen.com/subject/wxgeoqtx.html