單例模式 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);