php——20-单例模式

版权声明:未经同意,不得随意转载转载 https://blog.csdn.net/lucky541788/article/details/82951041

单例模式

  • 单例模式(也叫单件模式)是让一个类在内存中仅有一个实例。

单例模式的优势

  • 单例模式保证在整个应用程序的生命周期中,任何一个时刻,单例类的实例都只存在一个,从而更加高效的利用系统资源。

技术点:

  • 不能用 new类名 的方式来创建一个对象;
  • 禁止类的构造方法被重写;
  • 禁止类的实例被外界克隆;

问题:
反复调用创建类会在内存中占储存空间,重复过多内存会奔溃

class Db
{
    public function __construct()
    {
        echo '有新的Db类的对象创建了<br>';
    }
}

$db1 = new Db();
$db1 = new Db();
$db2 = new Db();//这种反复创建会在内存中占储存空间,重复过多内存会奔溃

不能用 new类名 的方式来创建一个对象(重点:用static调用自身)

<?php

class Db
{
    private static $db;//保存类的唯一实例对象

    private function __construct()
    {
        echo '有新的Db类的对象创建了<br>';
    }

    /**
     * 获取Db类的唯一实例对象
     */
    static function getDb()
    {
        //new Db();//不建议用,用new self()

        //判断 $db 是否被 new
        if (self::$db == null && !(self::$db instanceof self)) {
            //自身new个实例
            self::$db = new self();
        }
        return self::$db;
    }

    public function test(){
        echo '我是test方法.<br>';
    }
}

//$db=new Db();//构造方法私有化,不能new

//尽管创建多个,但是实际就显示一个
Db::getDb();
Db::getDb();
$db = Db::getDb();//有新的Db类的对象创建了

//调用单例中的公共方法
$db->test();//我是test方法.
Db::getDb()->test();//我是test方法.

禁止类的构造方法被重写(重点:final保护父类构造函数)

<?php

class Db
{
    private static $db;//保存类的唯一实例对象

    final private function __construct()
    {
        echo '有新的Db类的对象创建了<br>';
    }

    /**
     * 获取Db类的唯一实例对象
     */
    static function getDb()
    {
        //new Db();//不建议用,用new self()

        //判断 $db 是否被 new
        if (self::$db == null && !(self::$db instanceof self)) {
            //自身new个实例
            self::$db = new self();
        }
        return self::$db;
    }

    public function test()
    {
        echo '我是父类中的test方法.<br>';
    }
}

class Son extends Db
{
    /*
      public function __construct()//final修饰的父类无法重写
    {
        //parent::__construct();
        echo 'Son有新对象创建了<br>';
    }
    */

    public static function test1()
    {
        echo '我是子类中的test1方法。<br>';
    }
}

//$son=new Son();//报错,final 使构造函数不能被重写
$son1=Son::getDb();
$son2=Son::getDb();//有新的Db类的对象创建了  //只会创建这一个
//Son::getDb()->test1();//报错  //无法通过父类调用子类中新建的方法,只能一子类调用
Son::getDb()->test();//我是父类中的test方法.
Son::test1();//我是子类中的test1方法。

禁止类的实例被外界克隆(重点: private function __clone(){}阻止被克隆)

<?php

class Db
{
    private static $db;//保存类的唯一实例对象

    final private function __construct()
    {
        echo '有新的Db类的对象创建了<br>';
    }
    
    /*
    //当有当前类的对象被克隆时调用
    public function __clone()
    {
        // TODO: Implement __clone() method.
        echo '有对象被克隆了。<br>';
    }
    */

    //阻止克隆方法,之后克隆调用会报错
    private function __clone()
    {
        // TODO: Implement __clone() method.
    }

    /**
     * 获取Db类的唯一实例对象
     */
    static function getDb()
    {
        //判断 $db 是否被 new
        if (self::$db == null && !(self::$db instanceof self)) {
            //自身new个实例
            self::$db = new self();
        }
        return self::$db;
    }

}

$db = Db::getDb();//有新的Db类的对象创建了
/*
$db1 = clone $db;

//克隆出来的对象和被克隆的对象具有相同的属性和方法.
if($db == $db1){
    echo '克隆出来的对象和被克隆的对象具有相同的属性和方法.<br>';
}

//不是同一个对象. //说明克隆还是会占用内存
if($db===$db1){
    echo '是同一个对象.<br>';
}else{
    echo '不是同一个对象.<br>';
}
*/

猜你喜欢

转载自blog.csdn.net/lucky541788/article/details/82951041