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