单例模式(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);
}
}