<?php
class Singleton
{
/**
* Returns the *Singleton* instance of this class.
*
* @staticvar Singleton $instance The *Singleton* instances of this class.
*
* @return Singleton The *Singleton* instance.
*/
public static function getInstance()
{
static $instance = null;
if (null === $instance) {
$instance = new static();
}
return $instance;
}
/**
* Protected constructor to prevent creating a new instance of the
* *Singleton* via the `new` operator from outside of this class.
*/
protected function __construct()
{
}
/**
* Private clone method to prevent cloning of the instance of the
* *Singleton* instance.
*
* @return void
*/
private function __clone()
{
}
/**
* Private unserialize method to prevent unserializing of the *Singleton*
* instance.
*
* @return void
*/
private function __wakeup()
{
}
}
class SingletonChild extends Singleton
{
}
$obj = Singleton::getInstance();
var_dump($obj === Singleton::getInstance()); // bool(true)
$anotherObj = SingletonChild::getInstance();
var_dump($anotherObj === Singleton::getInstance()); // bool(false)
var_dump($anotherObj === SingletonChild::getInstance()); // bool(true)
当我们需要确保在Web应用程序的整个请求生命周期中只有一个类的示例时,单例模式非常有用。这通常发生在我们有全局对象(如Configuration类)或共享资源(如事件队列)时。 在使用单例模式时应该小心,因为它的本质是将全局状态引入到应用程序中,从而降低了可测试性。(并且应该)来代替单例类。使用依赖注入意味着我们没有在应用程序的设计中引入不必要的耦合,因为使用共享或全局资源的对象不需要具体定义的类的知识。 Singleton pattern on Wikipedia
4条答案
按热度按时间izkcnapc1#
例如:
输出:
Object1和Object2将指向同一示例
n6lpvg4x2#
单例类是一种特殊的类,正如您正确地指出的,它只能示例化一次。
第一点:它不是一个PHP相关的概念,而是一个OOP概念。
什么是“只示例化一次”?它只是简单地意味着,如果一个对象已经示例化,系统将返回它,而不是创建一个新的。为什么?因为,有时候,你需要一个“公共”示例(全局的)或者因为示例化一个已经存在的对象的“副本”是无用的。
让我们考虑第一种情况下的框架:在引导操作中,你需要示例化一个对象,但是你可以(你必须)与其他请求框架引导的人共享它。
对于第二种情况,让我们考虑一个只有方法而没有成员的类(因此基本上没有内部状态)。也许你可以把它实现为静态类,但是如果你想遵循设计模式,考虑AbstractFactory),你应该使用对象。所以,拥有一个只有方法的相同对象的副本是没有必要的,而且也是浪费内存的。
这是我使用singleton的两个主要原因。
vkc1a9a23#
是的,你是对的“它不能被示例化超过一次。”这个概念是非常有用的,当你打开一个数据库连接。
假设
如果有人登录,您就创建一个新的数据库对象.
如果有人更新了某个东西,您就创建了一个新的数据库对象。
如果有人注销,则创建一个新的数据库对象。
正如你所看到的,每次与数据库交互时,都会创建一个新的对象并打开一个新的连接。这在效率方面是一件坏事。
单例类真正解决了这个问题,它创建了一个数据库连接对象并保存它,无论何时需要它都只返回它而不是创建一个新的。
如您所见,该类检查现有连接($_instance属性),如果未设置,则返回该连接。
wmomyfyw4#
更多参考:Is there a use-case for singletons with database access in PHP?
从设计模式- PHP:正确的方法:
当设计web应用程序时,允许访问一个且仅一个特定类的示例在概念上和体系结构上通常是有意义的,单例模式使我们能够做到这一点。
上面的代码使用静态变量和静态创建方法
getInstance()
实现了单例模式。__construct
被声明为protected,以防止通过new操作符在类外部创建新示例。__clone
被声明为private,以防止通过clone操作符克隆类的示例。__wakeup
被声明为private,以防止通过全局函数unserialize()
对类的示例进行反序列化。getInstance()
中使用关键字static通过后期静态绑定创建一个新示例,这允许对示例中的类Singleton进行子类化。当我们需要确保在Web应用程序的整个请求生命周期中只有一个类的示例时,单例模式非常有用。这通常发生在我们有全局对象(如Configuration类)或共享资源(如事件队列)时。
在使用单例模式时应该小心,因为它的本质是将全局状态引入到应用程序中,从而降低了可测试性。(并且应该)来代替单例类。使用依赖注入意味着我们没有在应用程序的设计中引入不必要的耦合,因为使用共享或全局资源的对象不需要具体定义的类的知识。
Singleton pattern on Wikipedia