php与设计模式-单例模式

本文深入探讨单例模式的应用与实现,包括其在日志、数据库等公用类中的作用,以及不同实现方式如懒汉式、饿汉式和双重校验锁的优缺点。通过PHP示例代码展示如何确保类的单例特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

单例模式

应用:
日志,数据库等公用类
主要优点:

  • 提供了对唯一实例的受控访问。
  • 由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象单例模式无疑可以提高系统的性能。
  • 允许可变数目的实例。

主要缺点:

  • 由于单例模式中没有抽象层,因此单例类的扩展有很大的困难。
  • 单例类的职责过重,在一定程度上违背了“单一职责原则”。
  • 滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这将导致对象状态的丢失。
(懒汉,线程不安全)
public class Singleton { 
    private static Singleton instance; 
    private Singleton (){}   
    public static Singleton getInstance() { 
    if (instance == null) { 
        instance = new Singleton(); 
    } 
    return instance; 
    } 
}
 
 
(懒汉,线程安全)
public class Singleton { 
    private static Singleton instance; 
    private Singleton (){} 
    public static synchronized Singleton getInstance() { 
    if (instance == null) { 
        instance = new Singleton(); 
    } 
    return instance; 
    } 
}
 
(饿汉)(php不能用)
public class Singleton { 
private static Singleton instance = new Singleton(); 
    private Singleton (){} 
    public static Singleton getInstance() { 
    return instance; 
    }  
}

(双重校验锁)
public class Singleton { 
    private volatile static Singleton singleton; 
    private Singleton (){} 
    public static Singleton getSingleton() { 
    if (singleton == null) { 
        synchronized (Singleton.class) { 
        if (singleton == null) { 
            singleton = new Singleton(); 
        } 
        } 
    } 
    return singleton; 
    } 
}

/* 设计模式之单例模式
* $_instance必须声明为静态的私有变量
* 构造函数和析构函数必须声明为私有,防止外部程序new
* 类从而失去单例模式的意义
* getInstance()方法必须设置为公有的,必须调用此方法
* 以返回实例的一个引用
* ::操作符只能访问静态变量和静态函数
* new对象都会消耗内存
* 使用场景:最常用的地方是数据库连接。
* 使用单例模式生成一个对象后,
* 该对象可以被其它众多对象所使用。
*/
class Danli {
    //保存类实例的静态成员变量
    private static $_instance;
    //private标记的构造方法
    private function __construct(){
        echo 'This is a Constructed method;';
 
    }

    //创建__clone方法防止对象被复制克隆
    public function __clone(){
        trigger_error('Clone is not allow!',E_USER_ERROR);
    }

    //单例方法,用于访问实例的公共的静态方法
    public static function getInstance(){
        if(!(self::$_instance instanceof self)){
            self::$_instance = new self;
        }
        return self::$_instance;
    }

    public function test(){
        echo '调用方法成功';
    }
}
 
//用new实例化private标记构造函数的类会报错
//$danli = new Danli();
//正确方法,用双冒号::操作符访问静态方法获取实例
$danli = Danli::getInstance();
$danli->test();
//复制(克隆)对象将导致一个E_USER_ERROR
//$danli_clone = clone $danli;

请关注我的订阅号

订阅号.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码哥说

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值