单例模式 Singleton Pattern
常用的一种设计模式 通常用于数据库操作类, 以保证在一个访问内只有一个数据库连接实例. 该唯一实例只对当前页面有效, 这是不同与java,.net那些编译型语言. 也就是说, 每一个请求都至少打开一个数据库连接.
- 构造&析构函数私有化
- instance对象(集合)必须是静态的私有变量
- 提供一个(public)静态的方法
getInstance
, 返回实例对象
我们以一个连接类来演示一下:
- 数据库配置文件:
config\database.php
return [
'hostname' => '127.0.0.1',// 服务器地址
'hostport' => '3306',// 端口
'database' => 'test',// 数据库名
'username' => 'root', // 用户名
'password' => '123456',// 密码
'charset' => 'utf8',// 数据库编码
];
- 数据库连接类文件
singleton\Db.php
:
namespace singleton;
use \PDO;
class Db {
private static $instance = null;//数据库连接实例
private $link;//数据库连接
private function __construct() {
$config = require __DIR__.'/../config/database.php';//读取数据库配置
$this->link = new PDO('mysql:host='.$config['hostname'].';port='.$config['hostport'].';dbname='.$config['database'].';charset='.$config['charset'],$config['username'],$config['password']);
$this->link->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
$this->link->query('set names '.$config['charset'].';');
return $this->link;
}
public static function getInstance(){
if(self::$instance instanceof self){
return self::$instance;
} else {
self::$instance = new self();;
return self::$instance;
}
}
/**
* @param string $sql
* @return array
*/
public function query(string $sql){
//do something
return [];
}
//阻止外部克隆
private function __clone() {}
}
- 调用文件:
test.php
:
use singleton\Db;
require 'vendor/autoload.php';
$m_db = Db::getInstance();
$m_db->query();
这样就简单的实现了一个单例模式.
工厂方法模式 Factory Method Pattern
也叫工厂模式. 看名称, 包含了"方法", 简单来讲, 就是用一个函数来实现new 一个对象.
使用工厂模式的好处就是, 如果要new的类名称或者参数(名/顺序)修改了, 我们只要修改一个地方, 不需要全部修改.
1. 取代new的示例
class Animal
{
private $name;
public function __construct(string $name) {
$this->name = $name;
}
}
class Factory
{
public static function createAnimal(string $name){
return new Animal($name);
}
}
//直接new
$m_Animal = new Animal('dog');
//单例模式, new一个类, 可以全部走一个入口
$m_Animal2 = Factory::createAnimal('cat');
2. 调用单例模式类
比如上面的创建单例模式及其调用, 每次都要getInstance, 能不能简单一点? 可以
先建一个helper.php
, 用于存放helper方法
use singleton\Db;
require_once 'vendor/autoload.php';
/**
* @return Db
*/
function getDb(){
return Db::getInstance();
}
再建一个调用文件test2.php
:
require 'helper.php';
$sql = 'SELECT * FROM admins LIMIT 0,1';
$db = getDb();
$rs = $db->query($sql);
$rs2 = getDb()->query($sql);