单列模式
单例模式是一种创建型模式,它会限制应用程序,使其只能创建某一特定类>类型的一个单一的实例。举例来说,一个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