牛逼plus!原来单例模式竟然是这样用的
Posted autofelix
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛逼plus!原来单例模式竟然是这样用的相关的知识,希望对你有一定的参考价值。
〝 古人学问遗无力,少壮功夫老始成 〞
单例模式,其实就是每个类只有一个实例化的对象,我们通过这个唯一的对象去调用其中的方法。我们大家都知道一个类,只要在外部New一下,就会得到一个实例,而这些实例都会被系统分配内存开销。打个比方,这就像一个村子要喝水,没必要每个人都打一个井吧,这样太浪费财力和物力了,其实只要在村口打一口井就能解决所有人喝水的问题,其实单例模式就是这个思想,减少内存的开销,让系统把内存用到该用的地方去。其实这就是对内存的极限抠门的一种表现形式。
目录
一、普通类的实例化
- 普通类的实例化,一个new将会创建一个实例化内存空间
- 从结果#1,#2中可以看到,两个类的内存空间不一致
- 这将会导致系统内存开销增大
<?php
/**
* Class A
*/
class A {}
$a = new A();
$b = new A();
echo "<pre />";
var_dump($a);
var_dump($b);
- 结果
object(A)#1 (0) {
}
object(A)#2 (0) {
}
二、定义单例模式
- 单例模式的入门口诀是﹕三私一公
- 私有的构造方法﹕防止人为外部使用new进行创建这就是上面普通内的实例化了
- 私有的克隆方法﹕防止人为外部使用clone方法后进行实例化
- 私有的静态属性﹕用来存储单一的实例化对象
- 公有的静态方法﹕用来实现单一的实例化逻辑
- 从结果来看﹕两个类的对象内存空间都指向了#1,实现了单例模式的基础构建
<?php
/**
* Class database
*/
class database
{
/**
* @var $instance
*/
private static $instance;
/**
* 私有的构造方法,禁止外部实例化
* database constructor.
*/
private function __construct() {}
/**
* 私有的克隆方法,禁止外部克隆
*/
private function __clone() {}
/**
* 获取单例
* @return database
*/
public static function getInstance()
{
if(!self::$instance instanceof self) {
self::$instance = new self();
}
return self::$instance;
}
}
$a = database::getInstance();
$b = database::getInstance();
echo "<pre />";
var_dump($a);
var_dump($b);
- 结果
object(database)#1 (0) {
}
object(database)#1 (0) {
}
三、单例模式的应用
- 其实在项目中单例模式的应用很多,无非就是有些东西只需要实例化一个对象就行了,不需要多次进行实例化
- 这其中的应用场景常见的就包括PDO连接数据库,Redis的连接等等
- 其实我们可以脑补一下,比如数据库的连接,我们是不是只需要连接一次就够了,不需要多次进行连接,这不就减少了内存的开销吗
- 这里贴上实例代码,可根据需要自行完善
<?php
/**
* Class mysql
*/
class mysql
{
/**
* @var \\PDO
*/
private $pdo;
/**
* @var $instance
*/
private static $instance;
/**
* @var array
*/
private $_config = [
'host' => '127.0.0.1',
'post' => 3306,
'user' => 'root',
'password' => '',
'charset' => 'utf8',
'dbname' => 'autofelix',
'except' => 'PDO::ERRMODE_EXCEPTION'
];
/**
* mysql constructor.
*/
private function __construct() {}
/**
* 数据库链接
*/
public function connect()
{
try {
$dsn = "mysql:host={$this->_config['host']};port={$this->_config['post']};dbname={$this->_config['dbname']};charset={$this->_config['charset']}";
$this->pdo = new PDO($dsn, $this->_config['user'], $this->_config['password']);
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, $this->_config['except']);
} catch (PDOException $e) {
exit('数据库连接失败:' . $e->getMessage());
}
}
/**
* @param $sql
* @return array
*/
public function getAll($sql)
{
$this->sql = $sql;
$pdostatement = $this->pdo->query($sql);
return $pdostatement->fetchAll(PDO::FETCH_ASSOC);
}
/**
* @return mysql
*/
public static function getInstance()
{
if(!self::$instance instanceof self) {
self::$instance = new self();
}
return self::$instance;
}
private function __clone() {}
}
$mysql = mysql::getInstance();
$mysql->connect();
$sql = 'select * from autofelix_users where 1';
$result = $mysql->getAll($sql);
echo json_encode($result);
猜你喜欢:
以上是关于牛逼plus!原来单例模式竟然是这样用的的主要内容,如果未能解决你的问题,请参考以下文章