Site icon 时鹏亮的Blog

设计模式-单例模式

请知悉:本文最近一次更新为 7年 前,文中内容可能已经过时。

呐,一谈到设计模式就头疼,为毛嘞?汉字都认识,但是为毛要这么搞这么用,绝大多数人都搞不清楚。这种现象又是为毛嘞?那当然是因为接触的项目小导致的,一般接触到大型项目的时候,就可以很自然的发现其中用到的设计模式。而只有真实的读了代码,了解了逻辑,才有基础去理解设计模式中,为什么要这么设计。

理解建立在接触到真实的项目的基础上,经验也由此而来。所以一般新手看了设计模式都云里雾里的,根本原因就在于没有接触过对应的代码,没有阅读过相关的源码,又如何能理解为什么要这样设计呢?

今儿就拿单例模式来说说,能理解的理解,理解不了的就甭看了。

1.首先,为什么要用单例模式?

实际项目中,假设你需要N个模型中都需要用MySQL数据库,当然,数据库也是个对应的类,你N个模型要初始化N个数据库的类,就问你浪不浪费资源,浪不浪费连接数,傻不傻逼?
于是有大神就总结了这么个模式,叫做单例模式,核心就是一把梭:一次请求中,不管你初始化几次相同的数据库类,返回的对象都是最初初始化成功的那个。这样,就节省了资源,让数据库类复用。单例模式由此而来。

2.啥框架用了单例模式?

CodeIgniter这框架,缩写CI,就是典型的单例模式的框架。这货本质上,整个大框架就是一个单例,$ci作为超级变量通过引用传值的方式进行,任何地方使用get_instance()获取的永远是同一个CI对象。如此,确保不会浪费资源,以及各个对象在内部的一致性。

3.单例模式怎么搞?(以下部分摘自:PHP 单例模式解析和实战

3.1 需要一个保存类的唯一实例的静态成员变量:

private static $_instance;

3.2 构造函数和克隆函数必须声明为私有的,防止外部程序new类从而失去单例模式的意义:

private function __construct()
{
$this->_db = pg_connect('xxxx');
}
private function __clone()
{
}//覆盖__clone()方法,禁止克隆

3.3 必须提供一个访问这个实例的公共的静态方法(通常为getInstance方法),从而返回唯一实例的一个引用

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

4.单例模式示例代码

4.1 普通的数据库访问例子:

<?php
......
//初始化一个数据库句柄
$db = new DB(...);
//添加用户信息
$db->addUserInfo(...);
......
//在函数中访问数据库,查找用户信息
function getUserInfo()
{
$db = new DB(...);//再次new 数据库类,和数据库建立连接
$db = query(....);//根据查询语句访问数据库
}

4.2 应用单例模式对数据库进行操作:

<?php
class DB
{
private $_db;
private static $_instance;

private function __construct(...)
{
$this->_db = pg_connect(...);//postgrsql
}

private function __clone() {}; //覆盖__clone()方法,禁止克隆

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


public function addUserInfo(...)
{

}
public function getUserInfo(...)
{
}
}
//test
$db = DB::getInstance();
$db->addUserInfo(...);
$db->getUserInfo(...);

4.3 深入理解

<?php
class db {
public $conn;
public static $sql;
public static $instance=null;
private function __construct(){
require_once('db.config.php');
$this->conn = mysql_connect($db['host'],$db['user'],$db['password']);
if(!mysql_select_db($db['database'],$this->conn)){
echo "失败";
};
mysql_query('set names utf8',$this->conn);
}
public static function getInstance(){
if(is_null(self::$instance)){
self::$instance = new db;
}
return self::$instance;
}
/**
* 查询数据库
*/
public function select($table,$condition=array(),$field = array()){
$where='';
if(!empty($condition)){

foreach($condition as $k=>$v){
$where.=$k."='".$v."' and ";
}
$where='where '.$where .'1=1';
}
$fieldstr = '';
if(!empty($field)){

foreach($field as $k=>$v){
$fieldstr.= $v.',';
}
$fieldstr = rtrim($fieldstr,',');
}else{
$fieldstr = '*';
}
self::$sql = "select {$fieldstr} from {$table} {$where}";
$result=mysql_query(self::$sql,$this->conn);
$resuleRow = array();
$i = 0;
while($row=mysql_fetch_assoc($result)){
foreach($row as $k=>$v){
$resuleRow[$i][$k] = $v;
}
$i++;
}
return $resuleRow;
}
/**
* 添加一条记录
*/
public function insert($table,$data){
$values = '';
$datas = '';
foreach($data as $k=>$v){
$values.=$k.',';
$datas.="'$v'".',';
}
$values = rtrim($values,',');
$datas = rtrim($datas,',');
self::$sql = "INSERT INTO {$table} ({$values}) VALUES ({$datas})";
if(mysql_query(self::$sql)){
return mysql_insert_id();
}else{
return false;
};
}
/**
* 修改一条记录
*/
public function update($table,$data,$condition=array()){
$where='';
if(!empty($condition)){

foreach($condition as $k=>$v){
$where.=$k."='".$v."' and ";
}
$where='where '.$where .'1=1';
}
$updatastr = '';
if(!empty($data)){
foreach($data as $k=>$v){
$updatastr.= $k."='".$v."',";
}
$updatastr = 'set '.rtrim($updatastr,',');
}
self::$sql = "update {$table} {$updatastr} {$where}";
return mysql_query(self::$sql);
}
/**
* 删除记录
*/
public function delete($table,$condition){
$where='';
if(!empty($condition)){

foreach($condition as $k=>$v){
$where.=$k."='".$v."' and ";
}
$where='where '.$where .'1=1';
}
self::$sql = "delete from {$table} {$where}";
return mysql_query(self::$sql);

}

public static function getLastSql(){
echo self::$sql;
}



}
$db = db::getInstance();
//$list = $db->select('demo',array('name'=>'tom','password'=>'ds'),array('name','password'));
//echo $db->insert('demo',array('name'=>'最近你啦','password'=>'123'));
//echo $db->update('demo',array("name"=>'xxx',"password"=>'123'),array('id'=>1));
echo $db->delete('demo',array('id'=>'2'));
db::getLastSql();

补充:单例模式又称为职责模式。

其他参考:PHP设计模式(一)—单例模式(Singleton Pattern)
https://www.cnblogs.com/yuyu1993/p/5576010.html


如您从本文得到了有价值的信息或帮助,请考虑扫描文末二维码捐赠和鼓励。

尊重他人劳动成果。转载请务必附上原文链接,我将感激不尽。


与《设计模式-单例模式》相关的博文:

Exit mobile version