首先,設計模式出如今眼裏太屢次了,看了又看,忘了又忘,咋看咋忘,在作前端開發之時就看過相關型文章,水平有限,業務有限,看過的知識比如過往雲煙,匆匆而已,不留下一點痕跡,現在做爲一個php,我決定深深的探一下設計模式,對於項目的開發以及代碼的規範有着大大的好處。php
一、單例是設計模式裏最基礎的一種
二、我用過單例
三、我不是什麼大神,只是一個初轉後端的小白。前端
一、建立型設計模式的一種。
二、字面意思(單個例子,單個實例)。
複製代碼
一、在特定的場景裏,特定的類只能有一個實例。
二、節約內存。
複製代碼
一、自行實例化。
二、只有一個實例。
三、向全局暴露實例。
複製代碼
首先先模擬一個故事。數據庫
小時候最頭疼寫做業,語文做業,英語做業等等,很是多,而後寫做的時候須要用到筆,通常我是直接用一個筆寫完做業,不多是寫語文做業用一支筆,寫英語做業用另外一隻筆。而後以這個故事用代碼來描述一下。後端
代碼部分設計模式
一、先抽象一個筆類函數
class Pen {
public function __construct(){
echo "製做一支筆";
}
public function write() {
echo "我能夠寫字";
}
}
複製代碼
這個類叫作pen,有一個方法叫寫,通俗的講,抽象一個筆,這個筆有一個功能叫作寫字。測試
二、 而後使用它spa
class Xiaochen {
public function writeEnglish(): Pen {
$pen = new Pen();
$pen->write();
echo "寫英語<br>";
return $pen;
}
public function writeChinese(): Pen {
$pen = new Pen();
$pen->write();
echo "寫英語<br>";
return $pen;
}
}
複製代碼
抽象一我的,叫小陳,小陳今天要寫語文和數學做業(writeEnglish,writeChinese),而後小陳寫做業的時候確定要用到筆($pen=new Pen)。這樣就能夠完成了使用。 結果是這樣: 設計
三、而後咱們來判斷一下寫語文和寫做業是否是用的一支筆日誌
var_dump($writeChinesePen === $writeChinesePen);
答案是false。
複製代碼
由於雖然是統一的pen類實例出來的對象,可是兩個對象倒是不一樣的存在,至於爲何,不懂的能夠去補一下基礎。
四、修改pen類
class Pen {
// 定義靜態,全局可訪問的實例對象
private static $pen;
// 暴露一個實例化的方法,只能經過這個方法實例化
public static function getInstance() {
if(is_null(static::$pen)) {
static::$pen = new static;
}
return static::$pen;
}
public function write() {
echo "寫字";
}
}
複製代碼
一、首先預約義一個全局的屬性用來存儲實例對象,使用static,由於沒必要實例化就可使用。
二、製做一個方法,代替實例化,判斷,若是實例過,直接返回實例對象,else,進行實例化。
三、若是有人不知道,使用new操做符來實例這個類怎麼辦。(不懂的請觀看訪問控制相關的文檔)
答案是修改構造函數:
private function __construct(){
}
複製代碼
四、因爲類是繼承,那麼單例也就表明着單例類不可繼承,而且不可複製。
修改php內置的clone:
private function __clone() {
}
複製代碼
修改類不可繼承 final class Pen
這樣的話,這個筆類大體就完成了。不可經過new操做符進行實例,也不會建立多個實例。由於是static,因此全局均可以使用。
五、最終測試
final class Pen {
// 定義靜態,全局可訪問的實例對象
private static $pen;
// 暴露一個實例化的方法,只能經過這個方法實例化
public static function getInstance() {
if(is_null(static::$pen)) {
static::$pen = new static;
}
return static::$pen;
}
public function write() {
echo "寫字";
}
private function __construct(){
}
private function __clone() {
}
}
class Xiaochen {
public function writeEnglish(): Pen {
$pen = Pen::getInstance();
$pen->write();
echo "寫英語<br>";
return $pen;
}
public function writeChinese(): Pen {
$pen = Pen::getInstance();
$pen->write();
echo "寫數學<br>";
return $pen;
}
}
$xiaochen = new Xiaochen();
$writeEnglistPen = $xiaochen->writeEnglish();
$writeChinesePen = $xiaochen->writeChinese();
var_dump($writeChinesePen === $writeEnglistPen);
複製代碼
這樣就能夠保證全局只有一個實例,不會建立多個實例,只要實例過一次,就不會在建立第二個實例。
以單例開始設計模式之門,以上例子純屬我的編造,可能有寫不恰當,大神勿噴,單例在應用種我通常都用來初始化數據庫鏈接,日誌對象,以及須要設定全局只有一個實例的需求。