【PHP设计模式】单例模式

92 阅读1分钟

【写在前面】

        最近写一些关于PHP设计模式的文章,对常用设计模式进行总结,其中参考了关于设计模式的书籍、前辈的博客,以及自己的实际工作经验与体会。才疏学浅,如有疏漏,敬请交流。

       所谓设计模式,就是特定环境下同类问题的一种解决方案,与语言无关,随着各种各样问题的出现,编程界前辈们已经总结出一些具有共性的问题,及与其对应的解决方案。选择正确的设计模式,使得开发过程更高效、便捷,代码的可重用性、灵活性更高。

【单例模式】

      特点:单例模式就是指在类中只new一个实例化对象,用于避免资源的浪费。如Redis、MySQL等在应用中调用较为频繁的类,希望整个应用只实例化一个。

      结构: 4私有1公有。

      示例:一个单例Redis操作类:

<?php
namespace app\index\cache; 
class Dredis {

    //私有静态变量 防止类外部修改
    private static $_instance = null;
     
    //私有构造方法 防止类外部new
    private function __construct(){
        self::$_instance = new \Redis();
        $result = self::$_instance->connect('127.0.0.1',6379);
        if($result === false){
            throw new \Exception('redis connect error');
        }
    }
    
    //公有静态方法 引用一个实例对象
    public static function getInstance(){
        if(null === self::$_instance) {
            self::$_instance = new self();
        }
        return self::$_instance;
    }
    
    //防止克隆多个实例
    private function __clone(){
 
    }
    
    //防止反序列化
    private function __wakeup(){
 
    }

    //清除连接实例(可选)
    public static function clear()
    {
        self::$_instance = null;
    }
}

在其他类中写一个测试方法,调用单例Redis:

<?php
namespace app\index\controller;
use app\index\cache\Dredis;
class Test {
    public function redisTest(){
        $redis1 = Dredis::getInstance();
        var_dump($redis1);
        echo '<hr>';

        $redis2 = Dredis::getInstance();
        var_dump($redis2);
        echo '<hr>';

        $redis3 = Dredis::getInstance();
        var_dump($redis3);
    }
}

测试结果如下,多次调用为同一个实例:

 调用过程中如果清除实例,则会创建新的实例:

<?php
namespace app\index\controller;
use app\index\cache\Dredis;
class Test {
    public function redisTest(){
        $redis1 = Dredis::getInstance();
        var_dump($redis1);
        echo '<hr>';
        Dredis::clear();

        $redis2 = Dredis::getInstance();
        var_dump($redis2);
        echo '<hr>';
        Dredis::clear();

        $redis3 = Dredis::getInstance();
        var_dump($redis3);
        Dredis::clear();
    }
}