单例模式
单例模式
Alex单例模式
单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例。
不适用单例模式时:
1
2
3
4
5
6
7
8
9class Database
{
public $db = null;
public function __construct($config = array())
{
$dsn = sprintf('mysql:host=%s;dbname=%s', $config['db_host'], $config['db_name']);
$this->db = new PDO($dsn, $config['db_user'], $config['db_pass']);
}
}然后创建3个对象:
1
2
3
4
5
6
7
8
9
10
11
12
13$config = array(
'db_name' => 'test',
'db_host' => 'localhost',
'db_user' => 'root',
'db_pass' => 'root'
);
$db1 = new Database($config);
var_dump($db1);
$db2 = new Database($config);
var_dump($db2);
$db3 = new Database($config);
var_dump($db3);输出信息:
1
2
3
4
5
6object(Database)[1]
public 'db' => object(PDO)[2]
object(Database)[3]
public 'db' => object(PDO)[4]
object(Database)[5]
public 'db' => object(PDO)[6]每次new操作都会实例化一次类,就会增加一个数据库的连接,占用内存也在不断增大。
使用单例模式
基类上限制,只能实例化一次,如果实例化过,直接返回。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35class Database
{
// 声明$instance为私有静态类型,用于保存当前类实例化后的对象
private static $instance = null;
// 数据库连接句柄
private $db = null;
// 构造方法声明为私有方法,禁止外部程序使用new实例化,只能在内部new
private function __construct($config = array())
{
$dsn = sprintf('mysql:host=%s;dbname=%s', $config['db_host'], $config['db_name']);
$this->db = new PDO($dsn, $config['db_user'], $config['db_pass']);
}
// 这是获取当前类对象的唯一方式
public static function getInstance($config = array())
{
// 检查对象是否已经存在,不存在则实例化后保存到$instance属性
if(self::$instance == null) {
self::$instance = new self($config);
}
return self::$instance;
}
// 获取数据库句柄方法
public function db()
{
return $this->db;
}
// 声明成私有方法,禁止克隆对象
private function __clone(){}
// 声明成私有方法,禁止重建对象
private function __wakeup(){}
}实例化使用单利模式
1
2
3
4
5
6
7
8
9
10
11
12
13$config = array(
'db_name' => 'test',
'db_host' => 'localhost',
'db_user' => 'root',
'db_pass' => 'root'
);
$db1 = Database::getInstance($config);
var_dump($db1);
$db2 = Database::getInstance($config);
var_dump($db2);
$db3 = Database::getInstance($config);
var_dump($db3);输出信息: 获取到的资源ID都是一样的
1
2
3
4
5
6object(Database)[1]
private 'db' => object(PDO)[2]
object(Database)[1]
private 'db' => object(PDO)[2]
object(Database)[1]
private 'db' => object(PDO)[2]总结:
单例模式:单利模式在应用中最为常见。单利模式在运行时实例是唯一的,他们不允许被生成自身的副本。
所以__clone
、__wakeup
等复制克隆对象的魔术方法建议声明为私有方法。
单例模式
特点4私1公:私有静态属性:
private static $instance = null;
//用以保存类的实例化private function __construct(){}
// // 构造方法声明为私有方法,禁止外部程序使用new实例化,只能在内部newprivate function __clone(){}
// // 声明成私有方法,禁止克隆对象private function __wakeup(){}
// // 声明成私有方法,禁止重建对象
- 公有属性:
1 | //方法提供给外部本类的实例化对象 |
构造方法私有,克隆方法私有,重建方法私有,一个公共静态方法。