1. 程式人生 > >php——20-單例模式

php——20-單例模式

單例模式

  • 單例模式(也叫單件模式)是讓一個類在記憶體中僅有一個例項。

單例模式的優勢

  • 單例模式保證在整個應用程式的生命週期中,任何一個時刻,單例類的例項都只存在一個,從而更加高效的利用系統資源。

技術點:

  • 不能用 new類名 的方式來建立一個物件;
  • 禁止類的構造方法被重寫;
  • 禁止類的例項被外界克隆;

問題: 反覆呼叫建立類會在記憶體中佔儲存空間,重複過多記憶體會奔潰

class Db
{
    public function __construct()
    {
        echo '有新的Db類的物件建立了<br>';
    }
}

$db1 = new
Db(); $db1 = new Db(); $db2 = new Db();//這種反覆建立會在記憶體中佔儲存空間,重複過多記憶體會奔潰

不能用 new類名 的方式來建立一個物件

<?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方法.

禁止類的構造方法被重寫

<?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方法。

禁止類的例項被外界克隆

<?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>';
}
*/