概要
創建型模式
保證一個類僅有一個實例,並且提供一個訪問它的全局訪問點
特點
1、一個類只有一個實例
2、它必須自行創建這個實例
3、必須自行向整個系統提供這個實例
結構圖
主要角色
Singleton 定義一個Instance操作,允許客戶訪問它的唯一實例。Instance是一個類方法。負責創建它的唯一的實例。
優缺點
1、對唯一實例的受控訪問
2、縮小命名空間 單例模式是對全局變量的一種改進。它避免了那些存儲唯一實例的全局變量污染命名空間
3、允許對操作和表示的精華 單例類可以有子類。而且用這個擴展類的實例來配置一個應用是很容易的。你可以用你所需要的類的實例在運行時刻配置應用。
4、允許可變數目的實例(多例模式)
5、比類操作更靈活
適用性
1、當類只能有一個實例而且客戶可以從一個眾所周知的訪問點訪問它時
2、當這個唯一實例應該是通過子類化可擴展的。並且用戶應該無需更改代碼就能使用一個擴展的實例時。
單例模式php實例
代碼如下 復制代碼<?php
/**
* 單例模式
* ————-
* @author zhaoxuejie <[email protected]>
* @package design pattern
* @version v1.0 2011-12-14
*/
class Singleton {
//私有靜態成員變量,保存全局實例
private static $instance = NULL;
//私有構造方法,保證外界無法直接實例化
private function __construct(){}
//靜態方法,返回此類唯一實例
public static function getInstance(){
if(!isset(self::$instance)){
$c = __CLASS__;
self::$instance = new $c;
}
return self::$instance;
}
//測試用方法
public function info(){
return ‘ok’;
}
//防止克隆
public function __clone(){
throw new Exception(‘Error: Clone is not allowed.’);
}
}
$s = Singleton::getInstance();
echo $s->info();
?>
補充我看到另一篇關於單例模式介紹
代碼如下 復制代碼<?php
class EasyFramework_Easy_Mysql{
protected static $_instance = null;
private function __construct(){
}
public static function getInstance(){
if (self::$_instance === null){
self::$_instance = new self();
}
return self::$_instance;
}
protected function __clone(){
}
}
$x = EasyFramework_Easy_Mysql::getInstance();
var_dump($x);
?>
/*
* 1.第一步:
* 既然是單例,也就是只能實例化一次,也就代表在實例化時
* 不可能使用new關鍵字!!!!
* 在使用new關鍵字時,類中的構造函數將自動調用。
* 但是,如果我們將構造函數的訪問控制符設置為protected或private
* 那麼就不可能直接使用new關鍵字了!!!
* 第二步:
* 無論protected/private修飾的屬性或方法,請問在當前類的
* 內部是否可以訪問?---> 可以
* 第三步:
* 現在我們根本沒有辦法得到對象(因為你不能使用new關鍵字了),
* 第四步:靜態成員(包括屬性或方法)在訪問時,只能通過
* 類名稱::屬性()
* 類名稱::方法()
* 第五步:如果我現在存在一個靜態方法--> getInstance()
* 那麼在調用時就應寫成
* $object = EasyFramework_Easy_Mysql::getInstance()
* 如果,getInstance()方法可以得到唯一的一個對象
* 也就代表是所謂的單例模式了!!!
* 第六步,怎麼讓getInstace()只得到一個對象呢?
* 既然要得到對象,那麼肯定是:
* $variabl = new ????();
* 我們又知道靜態屬性的值是可以所有的對象來繼承的!!!
* 靜態成員是屬於類的,而非對象的!
* 所以:
* 第七步:聲明一個靜態的屬性,用其存儲實例化的對象
* protectd static $_instance
*
* 並且初始值為null
* 那麼我在調用getInstance()方法時,只需要判斷其值是否為空即可
*
* public static function getInstance(){
* if(self::_instance === null){
* self::_instance = new self();
* }
* return self::_instance;
* }
* 在實例時,一定是這樣寫:
* $x = EasyFramework_Easy_Mysql::getInstance();
* 在第一時調用時,類的$_instance這個靜態屬性值為null,
* 那麼也就代表,getInstance()方法的判斷條件為真了,
* 也就意味著
* self::$_instance這個成員有了值了!!!
* 並且還返回這個值
* $y = EasyFramework_Easy_Mysql::getInstance();
* 在第二次或第N次調用時,self::$_instance已經有了值了
* 也就代表getInstance()方法的條件為假了!!!
* 也就代表其中的程序代表不可能執行了!!!
* 也就代表將直接返回以前的值了!!!
*
*
*
* */