常用設計模式之PHP實現: 單例,工廠方法

單例模式 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);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章