看看這個類的執行個體化方式能否實現“單例模式”?

來源:互聯網
上載者:User
比如我有一個類,類名是A(這個類本身不是實現單例模式的,看後面執行個體化這個類的方式):

class A(){    public $str = '這是屬性';    public $str2 = '屬性';    private $str3 = '私人屬性';        public function __construct($a,$b,$c){        //構造方法    }        public function func1(){        //類的方法    }        public function func2(){        //類的方法    }}

還有一個全域函數:

function getObj(){    require PATH.'a.class.php';//引入上面定義的class A的檔案    static $instance;//定義靜態變數    if($instance){        return $instance;    }    $instance = new A('1','2','3');    return $instance;}

然後我要在其他地方調用類A的執行個體,並且可能需要一次請求調用多次,通過getObj方法來得到這個類的執行個體,因為是返回的靜態變數,其實在第一次建立這個類的執行個體後,後面調用都是直接用的這個靜態變數的執行個體,並沒有重新new一個新的執行個體,這種方式算不算單例模式??如果不算,主要是哪裡不同會有什麼隱患??十分感謝!

回複內容:

比如我有一個類,類名是A(這個類本身不是實現單例模式的,看後面執行個體化這個類的方式):

class A(){    public $str = '這是屬性';    public $str2 = '屬性';    private $str3 = '私人屬性';        public function __construct($a,$b,$c){        //構造方法    }        public function func1(){        //類的方法    }        public function func2(){        //類的方法    }}

還有一個全域函數:

function getObj(){    require PATH.'a.class.php';//引入上面定義的class A的檔案    static $instance;//定義靜態變數    if($instance){        return $instance;    }    $instance = new A('1','2','3');    return $instance;}

然後我要在其他地方調用類A的執行個體,並且可能需要一次請求調用多次,通過getObj方法來得到這個類的執行個體,因為是返回的靜態變數,其實在第一次建立這個類的執行個體後,後面調用都是直接用的這個靜態變數的執行個體,並沒有重新new一個新的執行個體,這種方式算不算單例模式??如果不算,主要是哪裡不同會有什麼隱患??十分感謝!

接下去就要是PHP7的時代了,你的代碼還停留在看上去像是5.x早期時代的PHP代碼,本身代碼應該可以跑通,你的使用方式從寬泛的定義上來講,勉強可以算單例,但是整體感覺非常奇怪。並且如別的回答提出的,如果別人不知道getObj函數的話,很有可能就自己new了,你的擷取對象的函數無法對別人起到約束作用

既然你的建構函式依賴三個參數,這是我對於這份代碼的建議實現

class A(){    public $str = '這是屬性';    public $str2 = '屬性';    private $str3 = '私人屬性';        private static $pool = [];        public static function getInstance($a, $b, $c)    {        /**         * 這裡假設一種情況是需要這三個參數這個對象才唯一         * 並且這三個參數都是可以轉換為字串類型的         *(也就是說不能是stream,array,或者沒有__toString()實現的object)         */        $key = implode('_', func_get_args());         if (!isset(self::$pool[$key])) {            /**             * 關於這裡使用static關鍵字詳情請看後期靜態繫結             * http://php.net/manual/zh/language.oop5.late-static-bindings.php             * 如果你的PHP還在用5.3以前的版本,請使用             * self::$pool[$key] = new self($a, $b, $c);             */            self::$pool[$key] = new static($a, $b, $c);         }                return self::$pool[$key];    }        protected function __construct($a, $b, $c)    {        //構造方法,沒有使用private是考慮如果有子類繼承的情況    }        public function func1()    {        //類的方法    }        public function func2()    {        //類的方法    }}

PS 另外建議題主去瞭解一下PSR規範和autoload

會報錯的,而且這種寫法很糟糕

其實不算。原因如下:
1.假設是多線程的環境,多個線程同時進入會不會同時產生多個對象呢,所以需要你進行冗餘處理。我不知道php是怎麼做的,但是Java可以通過sync關鍵字來搞定同步。
2.你建構函式是公有的,假設別人在你的代碼上二次開發,但他不知道你的這個getobj。他就會自己new一個。這樣也會有問題。

  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.