Singleton(单例模式):单例模式是最常见的模式之一,在Web应用的开发中,常常用于允许在运行时为某个特定的类创建仅有一个可访问的实例。
<?php
/**
* Singleton class[单例模式]
* @author ITYangs<ityangs@163.com>
*/
final class Mysql
{
/**
*
* @var self[该属性用来保存实例]
*/
private static $instance;
/**
*
* @var mixed
*/
public $mix;
/**
* Return self instance[创建一个用来实例化对象的方法]
*
* @return self
*/
public static function getInstance()
{
if (! (self::$instance instanceof self)) {
self::$instance = new self();
}
return self::$instance;
}
/**
* 构造函数为private,防止创建对象
*/
private function __construct()
{}
/**
* 防止对象被复制
*/
private function __clone()
{
trigger_error('Clone is not allowed !');
}
}
// @test
$firstMysql = Mysql::getInstance();
$secondMysql = Mysql::getInstance();
$firstMysql->mix = 'ityangs_one';
$secondMysql->mix = 'ityangs_two';
print_r($firstMysql->mix);
// 输出: ityangs_two
print_r($secondMysql->mix);
// 输出: ityangs_two
在很多情况下,需要为系统中的多个类创建单例的构造方式,这样,可以建立一个通用的抽象父工厂方法:
<?php
/**
* Singleton class[单例模式:多个类创建单例的构造方式]
* @author ITYangs<ityangs@163.com>
*/
abstract class FactoryAbstract {
protected static $instances = array();
public static function getInstance() {
$className = self::getClassName();
if (!(self::$instances[$className] instanceof $className)) {
self::$instances[$className] = new $className();
}
return self::$instances[$className];
}
public static function removeInstance() {
$className = self::getClassName();
if (array_key_exists($className, self::$instances)) {
unset(self::$instances[$className]);
}
}
final protected static function getClassName() {
return get_called_class();
}
protected function __construct() { }
final protected function __clone() { }
}
abstract class Factory extends FactoryAbstract {
final public static function getInstance() {
return parent::getInstance();
}
final public static function removeInstance() {
parent::removeInstance();
}
}
// @test
class FirstProduct extends Factory {
public $a = [];
}
class SecondProduct extends FirstProduct {
}
FirstProduct::getInstance()->a[] = 1;
SecondProduct::getInstance()->a[] = 2;
FirstProduct::getInstance()->a[] = 11;
SecondProduct::getInstance()->a[] = 22;
print_r(FirstProduct::getInstance()->a);
// Array ( [0] => 1 [1] => 11 )
print_r(SecondProduct::getInstance()->a);
// Array ( [0] => 2 [1] => 22 )