下面就让我来详细讲解一下 PHP 设计模式 Singleton(单例模式)的完整攻略。
什么是单例模式?
单例模式是一种创建型设计模式,它确保一个类只有一个实例,并且提供了一个全局访问点来访问这个实例。单例模式通常用于管理共享资源,例如数据库连接、日志文件等等。
单例模式的使用场景
当一个类的实例化需要耗费很多资源的时候,或者介于全局变量和局部变量之间,适合使用单例模式。
单例模式的实现方法
饿汉式实现
饿汉式实现是指单例模式在类加载的时候就创建了实例,因此也叫做静态单例模式。这种方式实现简单,线程安全,但是可能会浪费一些资源,因为不一定每次都需要实例化这个对象。实现方法如下:
class Singleton
{
private static $instance = new Singleton();
private function __construct()
{
}
public static function getInstance(): Singleton
{
return self::$instance;
}
}
懒汉式实现
懒汉式实现是指单例模式只有在第一次使用的时候才创建实例。这种实现方式避免了内存浪费的问题,但是需要考虑线程安全性问题。实现方法如下:
class Singleton
{
private static $instance;
private function __construct()
{
}
public static function getInstance(): Singleton
{
if (!isset(self::$instance)) {
self::$instance = new Singleton();
}
return self::$instance;
}
}
这种方式有一个线程安全问题,可能会出现同时创建两个实例的情况。可以在 getInstance
方法上加锁来解决。
class Singleton
{
private static $instance;
private function __construct()
{
}
public static function getInstance(): Singleton
{
if (!isset(self::$instance)) {
self::$instance = new Singleton();
}
return self::$instance;
}
public static function getInstanceThreadSafe(): Singleton
{
static $instance;
if (!isset($instance)) {
self::$instance = new Singleton();
}
return $instance;
}
}
单例模式的示例代码
下面给出两个单例模式的示例代码。
示例代码一:日志类
在例子中,我们模拟了一个日志类。日志类通过单例模式实现了只有一个实例,可以全局调用。
class Log
{
private static $instance;
private $logs = [];
private function __construct()
{
}
public static function getInstance(): Log
{
if (!isset(self::$instance)) {
self::$instance = new Log();
}
return self::$instance;
}
public function add($log)
{
$this->logs[] = $log;
}
public function printLogs()
{
foreach ($this->logs as $log) {
echo $log . "\n";
}
}
}
// example usage
$log = Log::getInstance();
$log->add('log 1');
$log->add('log 2');
$log->add('log 3');
$log->printLogs();
示例代码解析:
Log
类是一个单例类,它只需要在第一次使用的时候实例化,所以我们在getInstance
方法中实现单例模式。add
方法用于添加一条日志,printLogs
方法用于打印所有的日志。
示例代码二:数据库连接类
在例子中,我们模拟了一个数据库连接类。数据库连接类通过单例模式实现了保证只有一个数据库连接实例。
class Database
{
private static $instance;
private $db;
private function __construct()
{
$this->db = new PDO('mysql:host=localhost;dbname=test', 'root', 'password');
}
public static function getInstance(): Database
{
if (!isset(self::$instance)) {
self::$instance = new Database();
}
return self::$instance;
}
public function query($sql)
{
return $this->db->query($sql);
}
}
// example usage
$db = Database::getInstance();
$result = $db->query('SELECT * FROM users');
foreach ($result as $row) {
echo $row['id'] . ':' . $row['name'] . "\n";
}
示例代码解析:
Database
类是一个单例类,它只需要在第一次使用的时候实例化,所以我们在getInstance
方法中实现单例模式。query
方法用于执行 SQL 查询,返回的是PDOStatement
对象。
以上就是单例模式的完整攻略。单例模式在实际开发中非常常见,可以想象在一个应用程序中,可能需要访问的资源非常多,而我们不希望每次都去创建全新的实例,而是希望尽可能的减少资源的消耗。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:php设计模式 Singleton(单例模式) - Python技术站