概念
工厂设计模式提供获取某个对象的新实例的一个接口,同时使调用代码避免确定实际实例化基类步骤。
很多高级模式都是依赖于工厂模式。
好处
PHP中能够创建基于变量内容的类的新实例,减少主代码流中的基于条件复杂性;
同时如果类发生改变不需要所有的地方进行修改,只需要在工厂中进行修改
(无论对象被修改或者添加其他对象,Factory对象调用方式仍让是相同的)(集中实例化)
应用场景
做支付接口的时候,未来可能对应不同的支付网关:支付宝、财付通、网银在线等。
方便未来扩展,设计成工厂模式。定一个专门生产网关接口的工厂,抽象出来,
做成接口形式,让所有的子类都要实现它的接口。
以后加一个支付方式,要使用哪一种支付方式,改变一下参数即可。
在为用户注册的时候,分为很多种角色的用户。
比如册用户,匿名用户、管理员用户等。完全使用可以使用工厂的思想来实现,
代码也容易维护,为每种角色可以生成操作的类等等。
系统对接多个不同类型的数据库,mysql,oracle,sqlserver
示例代码
简单工厂模式Factory,提供一个工厂方法供客户端调用。可能违反开闭原则。
<?php
/**
*@class 服务端开发(不知道谁将会被调用)
*
*/
class dbmysql{
public function conn() {
echo '连接上了Mysql';
}
}
class dbsqlite{
public function conn() {
echo '连接上了sqlite';
}
}
/**
*@class 简单工厂,工厂方法
*
*/
class Factory{
public static function createDb($type = '') {
if($type == 'mysql') {
return new dbmysql();
}elseif($type == 'sqlite') {
return new dbsqlite();
}else{
throw new Exception("Error db type", 1);
}
}
}
/**
*@class 客户端看不到dbmysql dbsqlite内部细节的,只是知道接口
*/
$db = Factory::createDb('mysql');
$db = Factory::createDb('sqlite');
$db->conn();
工厂方法:一个工厂生产多个零件,但零件共同特点是属于一个产品。
此工厂可以生产产品,而非单独的对象。
<?php
interface db{
public function conn();
}
class dbmysql implements db{
public function conn() {
echo '连接上了Mysql';
}
}
class dbsqlite implements db{
public function conn() {
echo '连接上了sqlite';
}
}
interface Factory{
public function createDB();
}
class mysqlFactory implements Factory{
public function createDB() {
return new dbmysql();
}
}
class sqliteFactory implements Factory{
public function createDB() {
return new dbsqlite();
}
}
class oracleFactory implements Factory{
public function createDB() {
return new oracle();
}
}
class oracleDb implements db{
public function conn() {
echo '连接上了oracle';
}
}
$fact = new mysqlFactory();
$db = $fact->createDB();
$db->conn();
$fact = new sqliteFactory();
$db = $fact->createDB();
$db->conn();
$fact = new oracleFactory();
$db = $fact->createDB();
$db->conn();
示例三:通过常茹不同参数
class CDFactory{
public static function create($type)
{
$class = strtolower($type) . "CD";
return new $class;
}
}
$type = 'enhanced';$cd = CDFactory::create($type);
$type = '';$my_cd = CDFactory::create($type);
示例四:通过传入不同参数,动态实例化不同的类。
public function factory($db_config='') {
$db_config = $this->parseConfig($db_config);
if(empty($db_config['dbms']))
throw_exception(L('_NO_DB_CONFIG_'));
$this->dbType = ucwords(strtolower($db_config['dbms']));
$class = 'Db'. $this->dbType;
if(is_file(CORE_PATH.'Driver/Db/'.$class.'.class.php')) {
$path = CORE_PATH;
}else{
$path = EXTEND_PATH;
}
if(require_cache($path.'Driver/Db/'.$class.'.class.php')) {
$db = new $class($db_config);
if( 'pdo' != strtolower($db_config['dbms']) )
$db->dbType = strtoupper($this->dbType);
else
$db->dbType = $this->_getDsnType($db_config['dsn']);
if(APP_DEBUG) $db->debug = true;
}else {
throw_exception(L('_NOT_SUPPORT_DB_').': ' . $db_config['dbms']);
}
return $db;
}