美文网首页
设计模式 - 单例模式

设计模式 - 单例模式

作者: patiencing | 来源:发表于2017-04-05 03:48 被阅读0次
singleton_pattern

缘起

工作中写 API 接口, 需要连接数据库, 因为 MySQL 的连接资源是有限的, 所以为了避免因为反复连接数据库造成性能和资源的浪费, 所以考虑选择使用"单例模式"连接数据库.


"单例模式"的概念

"单例模式 / Singleton Pattern" 表示这个类只能造出一个对象. 如果用来连接数据库, 就能保证有且只连接一次数据库, 避免反复连接.


"单例模式"的特点及其逻辑推导

"单例模式"的主要特点“三私一公二静态”:
(这里为了让总结更简短, 把权限 privateprotected(即"非 public "的)统称为"私", 把权限 public 称为"公")

  • "构造函数"必须声明为私有的或者受保护的
  • "克隆函数"必须声明为私有的或者受保护的
  • 私有的或者受保护的静态的"变量"(通常命名为$_instance)
  • 提供一个访问这个实例的公共的静态的方法(通常命名为getInstance())

“三私一公二静态”逻辑推导:

  • 需要一个保存类的唯一实例的变量, 而且为了保证让这个类只有一个实例,该变量必须是一个静态变量 (static), 而且这个代表实例的变量只可以被后面的实例化方法 getInstance() 使用, 不可被外部访问, 设置为 private;
  • 需要提供一个访问这个实例的一个静态方法(通常命名为 getInstance() 方法), 从而返回唯一实例的一个引用, 避免了实例化出很多对象; 因为外部需要通过该方法来调用, 所以必须是"公共" (public) 的;
  • 为了防止类的外部 new 一个对象从而失去单例的意义(即, 避免这个类自身的构造函数创建对象),需要将"构造函数"设置成 protected 或者 private, 从而限制外部实例化出新对象;
  • 同样的, 为了避免外部通过克隆创建对象, 需要将"克隆函数"设置成 protected 或者 private;
  • 通过这些设置, 外部就只能通过唯一的接口 -- getInstance() 方法来创建一个静态的 "Singleton 类"

"单例模式"的经典代码

class Single{
    private static $_instance;
    
    private function __construct(){
    }
    
    private function __clone(){
        
    }
    
    public static function getInstance(){
        if(!(self::$_instance instanceof Single)){
            self::$_instance = new self();
        }
        return self::$_instance ;
    }
}

检验"单例模式"的效果

为了检验是否"有且只能生成一个对象", 可以在构造函数中生成随机数, 然后检验两次实例产生的随机数是否相同:

class Single{
    private static $_instance;
    
    private function __construct(){
        $this->rand = mt_rand(1000, 9999);
    }
    
    private function __clone(){
        
    }
    
    public static function getInstance(){
        if(!(self::$_instance instanceof Single)){
            self::$_instance = new self();
        }
        return self::$_instance ;
    }
}

$a = Single::getInstance();
$b = Single::getInstance();
echo $a->rand;
echo "\n";
echo $b->rand;

两者输出的随机数是一致的, 所以可以说明"单例模式"是成功的.


使用"单例模式"连接数据库

基于上面的有效的单例模式代码, 用于连接数据库:

class Db{
private static $_instance;
private static $_connect;
private $_dbConfig = array(
    'host'=>'127.0.0.1',
    'user'=>'root',
    'pwd'=>'vagrant',
    'database'=>'tpshop',
);

private function __construct(){
}

private function __clone(){
}

public static function getInstance(){
    if (!(self::$_instance instanceof self)){
        self::$_instance = new self();
    }
    return self::$_instance;
}

public function connect(){
    if(!self::$_connect){
        self::$_connect = mysql_connect($this->_dbConfig['host'], $this->_dbConfig['user'], $this->_dbConfig['pwd']);
        if(!self::$_connect){
            die( 'MySQL connect error'.mysql_error());
        }
        mysql_select_db($this->_dbConfig['databas'], self::$_connect);
        mysql_query('set names UTF8', self::$_connect);
    }
    return self::$_connect;
}
}

$connect = Db::getInstance()->connect();
var_dump($connect);

文章历史

  • 2016/11/22 (第一次发布)
  • 2017/03/23 开始阅读书籍"深入 PHP - 对象, 模式, 实践", 对"面向对象"有了进一步理解. 所以修改了章节"'单例模式'的特点及其逻辑推导".
  • 2017/07/04 按照 PSR 代码规范, static 需要放在"访问修饰符"前面; 修改标题;

如果你觉得我的文章对你有用, 请打个"喜欢", 或者给些改进的建议 _

相关文章

  • 单例模式Java篇

    单例设计模式- 饿汉式 单例设计模式 - 懒汉式 单例设计模式 - 懒汉式 - 多线程并发 单例设计模式 - 懒汉...

  • python中OOP的单例

    目录 单例设计模式 __new__ 方法 Python 中的单例 01. 单例设计模式 设计模式设计模式 是 前人...

  • 单例

    目标 单例设计模式 __new__ 方法 Python 中的单例 01. 单例设计模式 设计模式设计模式 是 前人...

  • 设计模式 - 单例模式

    设计模式 - 单例模式 什么是单例模式 单例模式属于创建型模式,是设计模式中比较简单的模式。在单例模式中,单一的类...

  • 设计模式

    常用的设计模式有,单例设计模式、观察者设计模式、工厂设计模式、装饰设计模式、代理设计模式,模板设计模式等等。 单例...

  • 2018-04-08php实战设计模式

    一、单例模式 单例模式是最经典的设计模式之一,到底什么是单例?单例模式适用场景是什么?单例模式如何设计?php中单...

  • python 单例

    仅用学习参考 目标 单例设计模式 __new__ 方法 Python 中的单例 01. 单例设计模式 设计模式设计...

  • 基础设计模式:单例模式+工厂模式+注册树模式

    基础设计模式:单例模式+工厂模式+注册树模式 单例模式: 通过提供自身共享实例的访问,单例设计模式用于限制特定对象...

  • 单例模式

    JAVA设计模式之单例模式 十种常用的设计模式 概念: java中单例模式是一种常见的设计模式,单例模式的写法...

  • 设计模式之单例模式

    单例设计模式全解析 在学习设计模式时,单例设计模式应该是学习的第一个设计模式,单例设计模式也是“公认”最简单的设计...

网友评论

      本文标题:设计模式 - 单例模式

      本文链接:https://www.haomeiwen.com/subject/xnctattx.html