PHP单例模式详解以及实际运用
什么是单例模式?
首先我们百度百科他怎么说?
单例模式,属于创建类型的一种常用的软件设计模式。通过单例模式的方法创建的类在当前进程中只有一个实例(根据需要,也有可能一个线程中属于单例,如:仅线程上下文内使用同一个实例)、
大白话:对于PHP而言 在一次生命周期中,如果使用了单例模式。我们不管实例化多少次。整个生命周期只会存在一个实例。
为什么要使用单例模式?
- 实例控制
单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例。 - 灵活性
因为类控制了实例化过程,所以类可以灵活更改实例化过程。
应用的场景
- Mysql连接
- Redis连接
- 等等其他连接
这些场景为什么要用到单例模式?
- 防止重复的实例化连接。造成连接浪费。在一次生命周期中,我们只要创建一次连接就可以了。
单例代码示例
- PHP代码示例
<?php
class Singleton
{
private static $instance = null;
// 禁止被实例化
private function __construct()
{
}
// 禁止clone
private function __clone()
{
}
// 实例化自己并保存到$instance中,已实例化则直接调用
public static function getInstance(): object
{
if (empty(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
public function test(): string
{
return '这是一个单例模式';
}
}
// 两次调用返回同一个实例
$single1 = Singleton::getInstance();
$single2 = Singleton::getInstance();
var_dump($single1, $single2);
echo $single1->test();
Golang代码示例
- (饿汉模式) 初始化就创建
package mian import "fmt" var instanse *singler type singler struct { Name string } func NewSingler()*singler{ return instanse } func init() { instanse = new(singler) instanse.Name = "test" } func main() { singler := NewSingler() fmt.Println(singler.Name) }
- (懒汉模式)需要的模式就创建
package main import ( "fmt" "sync" ) var instanse *singler var mutex sync.Mutex type singler struct { Name string } func NewSingler()*singler { if instanse == nil{ mutex.Lock() defer mutex.Unlock() if instanse == nil{ instanse = new(singler) instanse.Name = "test" } } return instanse } func main() { singler := NewSingler() fmt.Println(singler.Name) }