什么是单例模式
作为对象的创建模式,单例模式确保某一个类只有一个实例,并且对外提供这个全局实例的访问入口。它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用。
特点
- 需要一个保存类的唯一实例的静态成员变量;
- 构造函数、重建函数和克隆函数必须声明为私有的,防止外部程序创建或复制实例副本;
- 必须提供一个访问这个实例的公共静态方法,从而返回唯一实例的一个引用。
简称四私一公(三个私有方法、一个私有属性和一个公共方法)
使用单例的必要性
使用单例模式的好处很大,以数据库操作为例。若不采用单例模式,当程序中出现大量数据库操作时,每次都要执行new操作,每次都会消耗大量的内存资源和系统资源,而且每次打开和关闭数据库连接都是对数据库的一种极大考验和浪费。使用了单例模式,只需要实例化一次,不需要每次都执行new操作,极大降低了资源的耗费。
PHP 代码
<?php
/**
* 单例模式
* Class Db
*/
class Db
{
/**
* 使用一个静态变量记录db对象初始化时为 null
* @var object
*/
private static $instance = null;
/**
* 保存用户的自定义配置参数
* @var array
*/
private $config = [
// 数据库类型
'type' => 'mysql',
// 服务器地址
'hostname' => '',
// 数据库名
'database' => '',
// 用户名
'username' => '',
// 密码
'password' => '',
// 端口
'hostport' => '',
];
/**
* 构造器私有化:禁止从类外部实例化,外部无法 new db();
* Db constructor.
* @param $config array 配置
*/
private function __construct(array $config = []){
// 传进来的配置优先级更高
if (!empty($config)) {
$this->config = array_merge($this->config, $config);
}
//根据配置链接数据库
}
/**
* 克隆方法私有化:禁止从外部克隆对象
*/
private function __clone(){}
/**
* 私有化重建方法:防止反序列化
*/
private function __wakeup(){}
/**
* 使用静态方法去获取数据对象
* 获取时先判断db对象是否已经存在,如果存在则直接返回db对象反正则创建这个对象
* @param $config array 配置
* @return Db|null
*/
public static function getInstance(array $config = [])
{
if(is_null(self::$instance) || !self::$instance instanceof self){
self::$instance = new self($config);
}
return self::$instance;
}
/**
* 设置配置项
* @param $index
* @param $value
*/
public function set($index, $value)
{
$this->config[$index] = $value;
}
/**
* 读取配置项
* @param $index string 配置索引
* @return mixed string 配置值
*/
public function get($index)
{
return $this->config[$index];
}
/**
* 执行SQL
* @param $sql string SQL语句
*/
public function query($sql)
{
//TODO
echo $sql;
}
/**
* 销毁对象
*/
public function __destruct()
{
// TODO: Implement __destruct() method.
self::$instance = null;
}
}
//=======================单例模式调用===============================
$db = db::getInstance();
$db->query('select * from user;');
//结果
//select * from user;