工厂模式价值:
- 减少类之间的耦合
- 提高类的复用性
工厂模式(Factory)允许在代码执行时实例化对象。之所以被称为工厂模式是因为它负责“生产”对象。以数据库为例,工厂需要的就是根据不同的参数,生成不同的实例化对象。它只负责生产对象,而不负责对象的具体内容。
定义一个适配器接口:
<?php interface DbAdapter { /** * 数据库连接 * @param $config 数据库配置 * @return resource */ public function connect($config); /** * 执行数据库查询 * @param string $query 数据库查询SQL字符串 * @param mixed $handle 连接对象 * @return resource */ public function query($query, $handle); }
定义MySQL数据库操作类:
<?php class DbAdapterMysql implements DbAdapter { private $_dbLink; //数据库连接字符串表示 /** * 数据库连接函数 * @param $config 数据库配置 * @throws DbException * @return resource */ public function connect($config) { if($this->_dbLink = @mysql_connect($config->host . (empty($config->port) ? '' : ':' . $config->port), $config->user, $config->password, true)) { if(@mysql_select_db($config->database, $this->_dbLink)){ if($config->charset){ mysql_query("SET NAMES '{$config->charset}'", $this->_dbLink); } return $this->_dbLink; } } //数据库异常 throw new DbException(@mysql_error($this->_dbLink)); } /** * 执行数据库查询 * @param string $query 数据库查询SQL字符串 * @param mixed $handle 连接对象 * @return resource */ public function query($query, $handle) { if ($resource = @mysql_query($query, $handle)) { return $resource; } } }
SQLite数据库操作类:
<?php class DbAdapterSqlite implements DbAdapter { private $_dbLink; /** * 数据库连接函数 * @param $config 数据库配置 * @throws DbException * @return resource */ public function connect($config) { if ($this->_dbLink = sqlite_open($config->file, 0666, $error)) { return $this->_dbLink; } throw new DbException($error); } /** * 执行数据库查询 * @param string $query 数据库查询SQL字符串 * @param mixed $handle 连接对象 * @return resource */ public function query($query, $handle) { if ($resource = @sqlite_query($query, $handle)) { return $resource; } } }
定义一个工厂类,根据传入不同的参数生成需要的类:
<?php class sqlFactory { public static function factory($type) { if (include_once 'Drivers/' . $type . '.php') { $classname = 'DbAdapter' . $type; return new $classname; } else { throw new Exception('Driver not found'); } } }
调用:
$db = sqlFactory::factory('MySQL'); $db = sqlFactory::factory('SQLite');