假设要实现一个功能,要封装访问数据库的操作。
1. 不实用设计模式的情况:
/**
*文件列表
*|
*|--Database.php 数据库封装类
*|--main.php 使用程序(客户端)
*/
/**
* Database.php 数据库封装
*/
class Database{
public $connect = null;
function select(){
//...
}
function insert(){
//...
}
function update(){
//...
}
function delete(){
//...
}
}
/**
* main.php
*/
$db = new Database();
$db->select();
//缺点:耦合严重,不好扩展
2. 简单工厂
/**
*文件列表
*|--drivers 数据库连接封装
|-- BaseDrivers.php 产品超类
|-- Mysql.php 具体的产品
|-- TiDb.php 另一个具体的产品
*|--DbFactory.php 数据库工厂
*|--main.php 使用程序(客户端)
*/
/**
* DbFactory.php 数据库工厂(简单工厂,产品是指定类型的数据库操作具柄)
*/
class DbFactory
{
public static function getDatabase($name):Database
{
if($name == "mysql"){
return new Mysql();
}else if($name = "tidb"){
return new TiDb();
}
throw new \Exception("driver not find:".$name);
}
}
/**
* BaseDrivers.php 数据库驱动基础类(简单工厂模式中的产品的超类,定义产品接口)
*/
abstract class BaseDrivers
{
public $connect = null;
abstract function select();
abstract function insert();
abstract function update();
abstract function delete();
}
/**
* Mysql.php mysql 数据库驱动类(具体的产品)
*/
class Mysql extends BaseDrivers
{
function select()
{
// TODO: Implement select() method.
}
function insert()
{
// TODO: Implement insert() method.
}
function update()
{
// TODO: Implement update() method.
}
function delete()
{
// TODO: Implement delete() method.
}
}
/**
* TiDb.php tidb数据库驱动类(另一种具体的产品)
*/
class TiDb extends BaseDrivers
{
function select()
{
// TODO: Implement select() method.
}
function insert()
{
// TODO: Implement insert() method.
}
function update()
{
// TODO: Implement update() method.
}
function delete()
{
// TODO: Implement delete() method.
}
}
/**
* main.php
*/
$database = DbFactory::getDatabase('mysql');//获取mysql的数据库操作
$database->select();
//优点:不说了,自行百度
//缺点:如果在添加其他的数据库类型操作,必须得修改DbFactory.php,增加 if...else... ,然后才能在main中获取新的数据库操作句柄
3. 工厂方法模式
/**
*文件列表
*|--drivers 数据库连接封装
|-- BaseDrivers.php 产品超类
|-- Mysql.php 具体的产品
|-- TiDb.php 另一个具体的产品
*|--factories.php 工厂封装
* |-- BaseFactory.php 工厂超类
* |-- MysqlFactory.php 具体工厂(只生产mysql产品的工厂)
* |-- TiDbFactory.php 另一个具体的工厂(只生产TiDb产品的工厂)
*|--main.php 使用程序(客户端)
*/
/**
* BaseFactory.php 工厂超类
*/
interface BaseFactory
{
function getDb();
}
/**
* MysqlFactory.php mysql工厂
*/
class MysqlFactory implements BaseFactory
{
function getDb()
{
return new Mysql();
}
}
/**
* TiDbFactory.php TiDb工厂
*/
class TiDbFactory implements BaseFactory
{
function getDb()
{
return new TiDb();
}
}
/**
* BaseDrivers.php 数据库驱动基础类
*/
abstract class BaseDrivers
{
public $connect = null;
abstract function select();
abstract function insert();
abstract function update();
abstract function delete();
}
/**
* Mysql.php mysql 数据库驱动类
*/
class Mysql extends BaseDrivers
{
function select()
{
// TODO: Implement select() method.
}
function insert()
{
// TODO: Implement insert() method.
}
function update()
{
// TODO: Implement update() method.
}
function delete()
{
// TODO: Implement delete() method.
}
}
/**
* TiDb.php tidb数据库驱动类
*/
class TiDb extends BaseDrivers
{
function select()
{
// TODO: Implement select() method.
}
function insert()
{
// TODO: Implement insert() method.
}
function update()
{
// TODO: Implement update() method.
}
function delete()
{
// TODO: Implement delete() method.
}
}
/**
* main.php
*/
$database = MysqlFactory::getDb();
$database->select();
//优点:新增数据库类型时,不用在修改框架部分代码(没有了Factory.php,不用在依赖这个类了)。只需要新添加一个对应的工厂,然后新增加一个数据库driver(产品),就可以直接在客户端(main.php)使用了,完全不影响其他的已经完成的功能。