牛逼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!原来观察者模式竟然是这样用的

牛逼plus!原来策略模式竟然是这样用的

牛逼plus!原来适配器模式竟然是这样用的

牛逼plus!原来工厂模式竟然是这样用的

牛逼plus!原来单例模式竟然是这样用的

以上是关于牛逼plus!原来单例模式竟然是这样用的的主要内容,如果未能解决你的问题,请参考以下文章

牛逼plus!原来策略模式竟然是这样用的

牛逼plus!原来观察者模式竟然是这样用的

牛逼plus!原来工厂模式竟然是这样用的

面向对象编程思想--单例模式

秃头竟然是原罪, 单例模式(Singleton Pattern)带你唱小白船

自己动手实现牛逼的单例模式