<?php
// 共同接口
interface db{
function conn();
}
// 服务端开发(不知道将会被谁调用)
class dbmysql implements db{
public function conn(){
echo '连接上mysql';
}
}
class dbsqlite implements db{
public function conn(){
echo '连接上sqlite';
}
}
// $db = new dbmysql();
// $db->conn();
// $db = new dbsqlite();
// $db->conn();
// 以上是面向接口开发,客户端看不到dbmysql,dbsqlite的内部细节,
// 只知道这两个类实现了db接口
// 但是存在安全隐患是,我们不希望客户端知道有这两个类的存在,
// 所以我们将用到下面的简单工厂模式
// ===== 简单工厂模式 ======
// 通过加入这个工厂类,现在客户端就不知道服务端有哪些类名了
// 只知道服务端开放了一个Factory::createDB方法
// 该方法只允许传递数据库名称
// class Factory{
// public static function createDB($type){
// if($type == 'mysql'){
// return new dbmysql();
// }else if($type == 'sqlite'){
// return new dbsqlite();
// }else{
// throw new Exception("Error db type",1);
// }
// }
// }
// $mysql = Factory::createDB('mysql');
// $mysql->conn();
// $mysql = Factory::createDB('sqlite');
// $mysql->conn();
// 简单工厂实现了隐秘性需求,但是新的问题来了,如果新增oracle类型,怎么办?
// 服务端要修改Factory的内容(在java,c++中,修改后还需要编译)
// 在面向对象设计法则中,重要的开闭原则 --- 对于修改是封闭的,对于扩展是开放的
// 为满足该原则,我们需要限满足根据不的选择逻辑提供不同的构成工厂,
// 而多个工程还需要一个统一的抽象工厂
// 所以,我们需要用到一个新的模式,抽象工厂模式
//
// ====== 抽象工厂模式 =======
// 首先需要一个统一的抽象工厂接口,用于创建多个工厂
interface Factory{
function createDB();
}
class mysqlFactory implements Factory{
public function createDB(){
return new dbmysql();
}
}
class sqliteFactory implements Factory{
public function createDB(){
return new dbsqlite();
}
}
// 客户端开始
$fact = new mysqlFactory();
$db = $fact->createDB();
$db->conn();
$fact = new sqliteFactory();
$db = $fact->createDB();
$db->conn();
// 当需要新增一个创建oracle数据连接方法时
// 在服务端添加oracle类
class dboracle implements db{
public function conn(){
echo '连接上oracle';
}
}
// 在服务端创建一个工厂类
class oracleFactory implements Factory{
public function createDB(){
return new dboracle();
}
}
$fact = new oracleFactory();
$db = $fact->createDB();
$db->conn();
// 抽象工厂对原有代码不做修改,而是新增方法代码
// 实现了面向对象的设计法则
?>