PHP设计模式:单例模式
目的
在整个应用程序的生命周期内(从脚本启动到结束),只能获得单例类的一个对象实例。
单例模式常用于如数据库连接等场景,多个类可以共用一个数据库连接对象,而不必每次都去 new
一个新对象,这样可以避免连接数递增导致的资源浪费。
实现原理
单例模式通过以下几个关键点来实现:
- 私有化
__construct
构造函数:防止外部通过new
创建多个实例。 - 私有化
__clone
:防止外部克隆实例,创建副本。 - 私有化
__wakeup
:防止反序列化创建新的实例。 - 提供静态方法
getInstance()
:用于返回该类的唯一实例。
代码实现
class Singleton
{
/**
* @var Singleton 唯一实例
*/
private static $instance;
/**
* 获取实例的静态方法,通过懒加载在第一次使用时创建实例
*
* @return Singleton 唯一实例
*/
public static function getInstance(): Singleton
{
if (null === static::$instance) {
static::$instance = new static();
}
return static::$instance;
}
/**
* 构造函数私有化,防止从外部创建新的实例
*/
private function __construct()
{
}
/**
* 禁止克隆,防止外部克隆对象
*/
private function __clone()
{
}
/**
* 禁止反序列化,防止通过反序列化创建新实例
*/
private function __wakeup()
{
}
}
测试
$singleton1 = Singleton::getInstance();
var_dump($singleton1);
$singleton2 = Singleton::getInstance();
var_dump($singleton2);
// 尝试直接实例化将会抛出错误
$singleton3 = new Singleton();
var_dump($singleton3);
测试结果
object(Singleton)#1 (0) {
}
object(Singleton)#1 (0) {
}
Fatal error: Uncaught Error: Call to private Singleton::__construct()
从测试结果可以看到:
$singleton1
和$singleton2
是同一个对象实例,表明单例模式成功实现。$singleton3
由于直接实例化而报错,验证了通过私有化__construct
限制了外部创建多个实例。
总结
通过单例模式,我们可以确保在应用程序的生命周期中,某个类只能有一个对象实例。这样的设计在需要共享资源(例如数据库连接、日志管理等)时尤为重要,能够节省资源、提高系统性能。