在OOP中,一個對象只負責一個特定的任務通常是一種很好的做法。例如,你也許希望只讓一個對象去訪問數據庫。單例模式被認為是職責模式,這是因為它將創建對象的控制權委托到一個單一的訪問點上。
在任何時候,應用程序中都會只有這個類僅有的一個實例存在。
這可以防止我們去打開數據庫的多個連接,或者不必要得使用多余的系統資源。
在更加復雜的系統中,使用單例模式在維持系統程序狀態的同步方面也尤其有用。
所有的單例模式至少擁有以下三個公共元素:
它們必須擁有一個構造函數,并且被標記為PRivate。它們擁有一個保存類的實例的靜態成員變量。它們擁有一個訪問這個實例的公共的靜態方法。和普通類不同的是,單例模式不能在其它類中直接實例化。單例模式只能被其自身實例化。要獲得這種限制效果,__construct()方法必須被標記為private。如果試圖用private構造函數構造一個類,就會得到一個可訪問性級別的錯誤。
要讓單例類起作用,就必須使其為其他類提供一個實例,用它調用各種方法。單例類不會創建實例副本,而是會向單例類內部存儲的實例返回一個引用。結果是單例類不會重復占用內存和系統資源,從而讓應用程序的其他部分更好的使用這些資源。作為這一模式的一部分,必須創建一個空的私有的__clone()方法,以防止對象唄復制或者克隆。
返回實例引用的這個方法通常被命名為getInstance()。這個方法必須是靜態的,而且如果它還沒有實例化,就必須實例化。getInstance()方法通過使用instanceof操作符和self關鍵字,可以檢測到類是否已經被初始化。如果保存實例的靜態成員為空或者還不是類自身的一個實例,那么這個實例將會被創建并保存到存放實例的變量中。
可以看出,兩次getInstance()只調用了一次構造函數。
對于數據庫連接,一個例子是
<?phpclass Database{ private $_db; static $_instance; private function __construct() { $dsn = ''; $this->_db = new PDO($dsn); } private function __clone() { } public static function getInstance() { if(!(self::$_instance instanceof self)){ self::$_instance = new self(); } return self::$_instance; } public function getPDO() { return $this->_db; }}$database = Database::getInstance();$pdo = $database->getPDO();新聞熱點
疑難解答
圖片精選