初探設計模式之建立型---單例(php)

序言

首先,設計模式出如今眼裏太屢次了,看了又看,忘了又忘,咋看咋忘,在作前端開發之時就看過相關型文章,水平有限,業務有限,看過的知識比如過往雲煙,匆匆而已,不留下一點痕跡,現在做爲一個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);
    複製代碼

這樣就能夠保證全局只有一個實例,不會建立多個實例,只要實例過一次,就不會在建立第二個實例。

總結

以單例開始設計模式之門,以上例子純屬我的編造,可能有寫不恰當,大神勿噴,單例在應用種我通常都用來初始化數據庫鏈接,日誌對象,以及須要設定全局只有一個實例的需求。

相關文章
相關標籤/搜索