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 )