单例模式
作用:
保证一个类只有一个实例来提供全局的访问点。可以避免对象的频繁创建和销毁,减少内存、资源开销。
类图:
- 角色划分:
- 图示:
代码:
class Singleton {
// 唯一实例
private static $_instance = null;
public function __construct() {
echo "单例模式的实例被构造了";
echo PHP_EOL;
}
public static function getInstance() {
if (!(self::$_instance instanceof Singleton)) {
self::$_instance = new Singleton();
}
return self::$_instance;
}
// 防止克隆
public function __clone() {}
}
// 测试
$test1 = Singleton::getInstance();
$test2 = Singleton::getInstance();
print_r($test1 === $test2);
实例:
<?php
/*
* mysql 单例
*/
class mysql{
private $host ='localhost'; //数据库主机
private $user = 'root'; //数据库用户名
private $pwd = ''; //数据库用户名密码
private $database = 'imoro_imoro'; //数据库名
private $charset = 'utf8'; //数据库编码,GBK,UTF8,gb2312
private $link; //数据库连接标识;
private $rows; //查询获取的多行数组
static $_instance; //存储对象
/**
* 构造函数
* 私有
*/
private function __construct($pconnect = false) {
if (!$pconnect) {
$this->link = @ mysql_connect($this->host, $this->user, $this->pwd) or $this->err();
} else {
$this->link = @ mysql_pconnect($this->host, $this->user, $this->pwd) or $this->err();
}
mysql_select_db($this->database) or $this->err();
$this->query("SET NAMES '{$this->charset}'", $this->link);
return $this->link;
}
/**
* 防止被克隆
*
*/
private function __clone(){}
public static function getInstance($pconnect = false){
if(FALSE == (self::$_instance instanceof self)){
self::$_instance = new self($pconnect);
}
return self::$_instance;
}
/**
* 查询
*/
public function query($sql, $link = '') {
$this->result = mysql_query($sql, $this->link) or $this->err($sql);
return $this->result;
}
/**
* 单行记录
*/
public function getRow($sql, $type = MYSQL_ASSOC) {
$result = $this->query($sql);
return @ mysql_fetch_array($result, $type);
}
/**
* 多行记录
*/
public function getRows($sql, $type = MYSQL_ASSOC) {
$result = $this->query($sql);
while ($row = @ mysql_fetch_array($result, $type)) {
$this->rows[] = $row;
}
return $this->rows;
}
/**
* 错误信息输出
*/
protected function err($sql = null) {
//这里输出错误信息
echo 'error';
exit();
}
}
//用例
$db = mysql::getInstance();
$db2 = mysql::getInstance();
$data = $db->getRows('select * from blog');
//print_r($data);
//判断两个对象是否相等
if($db === $db2){
echo 'true';
}
?>
优缺点:
- 优点:
1)在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例 ;
2)避免对资源的多重占用(比如写文件操作) 。 - 缺点:
1)没有抽象层,因此单例类的扩展有很大的困难 ;
2)单例类的职责过重,在一定程度上违背了“单一职责原则” 。