單列模式
單例模式是一種創建型模式,它會限制應用程序,使其只能創建某一特定類>類型的一個單一的實例。舉例來說,一個web站點將會需要一個數據庫連接>對象,但是應該有且只能有一個,因此我們通過使用單例模式來實現這種限>制。
我們可以使用一個靜態屬性來保證對於一個特定的類來說只存在一個單一的>實例。
Class someclass{
Static private $_instance = NULL;
}
【示例】config類實現了單例模式,以便整個web應用程序可以使用同一個配置對象。
[php] view plain copy
<?PHP
class config{
//$_instance 屬性代表類的單一實例,$_settings屬性,存儲配置信息
static private $_instance = NULL;
private $_settings = array();
private function __construction(){}
private function __clone(){}
static function getInstance(){
if(self::$_instance == NULL){
self::$_instance = new cinfig();
}
return self::$_instance;
}
function set($index,$value){
$this->_settings[$index] = $value;
}
function get($index){
return $this -> _settings[$index];
}
}
?>
【示例】使用config類
[php] view plain copy
<?PHP
require('danli.php');
$CONFIG = config::getInstance();
//創建一個設置條目
$CONFIG ->set('live','true');
//打印出設置的值
echo'<p>$CONFIG["live"]:'.$CONFIG->get('live').'</p>';
//創建另一個配置對象,並確認設置的值。
$TEST = config::getInstance();
echo'<p>$TEST"live"]:'.$TEST->get('live').'</p>';
?>
注意:從理論上來說,位於類外部的代碼可以控制類的實例的數量,然而我們使用面向對象編程,並且一個類至少得有一個實例,那麼在類中實現這種功能是最佳的選擇
二、實現單例模式所要考慮的問題
1
問題1:只能有一個實例,new是罪惡的根源,想辦法讓外部不能new如何解決?
解決方法:通過將構造方法,保護或私有化,外部即不能生成實例了。
2
問題2:不能new了,那不成0例模式了嗎?那總得想辦法生成一個實例吧?
解決方法:既然在外部不能new了,內部可以new啊,所以決定在內部通過靜態方法new一個實例。
3
問題3:現在有實例了,但外部每次調用靜態方法生成實例,都不是一個對象。 如何防止呢?
解決方法:在內部將這個實例保存下來,並做判斷。
4
問題4:如果繼承一下,通過子類new對象,每次生成的都不是同一個對象了,如何解決?
解決方法:利用關鍵字“final“修飾生成實例的方法即可。
5
問題5:在外部通過clone函數克隆一個對象,此對象又發生了變化,如何解決?
解決方法:利用__clone魔術方法 解決此問題。
<?php
class single{
static public $object = null;
protected function __construct(){
}
final static function NewOb(){
if (self::$object instanceof self) {
return self::$object;
}
self::$object = new self();
return self::$object;
}
public function __clone(){
echo "想克隆沒門<br />";
}
}
$t1 = single::NewOb();
$t2 = single::NewOb();
$t3 = clone $t2;
if ($t1 === $t2) {
echo '是一個對象<br />';
}else {
echo '不是一個對象<br />';
}
if ($t3 === $t2) {
echo '是一個對象<br />';
}else {
echo '不是一個對象<br />';
}
?>
php中的懶漢單列式
class test {
private static $_instance;
public static function getInstance(){
if(!self::$_instance){
self::$_instance = new self();
}
return self::$_instance;
}
private function __construct(){
//檢查實例化
echo "instance\n";
}
}
$a = test::getInstance();
var_dump($a);
結果:
//instance
//object(test)[1]
實例代碼
<?php
class Preferences
{
private $props = [];
private static $instance;
private function __construct(){}
public static function getIntance()
{
if(empty( self::$instance ))
self::$instance = new Preferences();
return self :: $instance;
}
public function setProperty ($key,$value)
{
$this -> props[$key] = $value;
}
public function getProperty($key)
{
return isset($this->props[$key]) ? $this -> props[$key]:null;
}
}
$pref = Preferences::getIntance();
$pref -> setProperty('zhangsan','www.net.com');
echo $pref -> getProperty('zhangsan');
?>
輸出://www.net.com