php——20-單例模式
阿新 • • 發佈:2018-12-13
單例模式
- 單例模式(也叫單件模式)是讓一個類在記憶體中僅有一個例項。
單例模式的優勢
- 單例模式保證在整個應用程式的生命週期中,任何一個時刻,單例類的例項都只存在一個,從而更加高效的利用系統資源。
技術點:
- 不能用 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>';
}
*/