适配器模式
将某个对象的接口适配为另一个对象所期望的接口,例如某个操作数据库的有多种不同的数据库操作方法,通过适配器统一成一个接口
目录结构
|adpater #项目根目录
|--Think #核心类库
|----Database #数据库操作类
|------MySQLAdapter.php #MySQL类
|------MySQLiAdapter.php #MySQLi类
|------PDOAdapter.php #PDO类
|----Loder.php #自动加载类
|----Target.php #数据库适配器接口类
|----DataBase.php #统一的数据库类
|--index.php #单一的入口文件
代码实现
数据库适配器接口类 Think/Target.php
<?php
namespace Think;
//定义一个数据库的适配器接口类
interface Target{
function connect($host, $user, $passwd, $dbname);
function query($sql);
function close();
}
MySQLAdapter类 Think/Database/MySQLAdapter.php
<?php
namespace Think\Database;
use Think\Target;
class MySQLAdapter implements Target{
protected $conn; //用于存放连接数据库句柄
//实现连接方法
public function connect($host, $user, $passwd, $dbname) {
$conn = mysql_connect($host, $user, $passwd);
mysql_select_db($dbname, $conn);
$this->conn = $conn;
}
//查询方法
public function query($sql) {
$res = mysql_query($sql, $this->conn);
return $res;
}
//关闭方法
public function close() {
mysql_close($this->conn);
}
}
MySQLiAdapter类 Think/Database/MySQLiAdapter.php
<?php
namespace Think\Database;
use Think\Target;
class MySQLiAdapter implements Target{
protected $conn; //用于存放连接数据库句柄
//实现连接方法
public function connect($host, $user, $passwd, $dbname) {
$conn = mysqli_connect($host, $user, $passwd, $dbname);
$this->conn = $conn;
}
//查询方法
public function query($sql) {
$res = mysqli_query($this->conn , $sql);
return $res;
}
//关闭方法
public function close() {
mysqli_close($this->conn);
}
}
PDOAdapter类 Think/Database/PDOAdapter.php
<?php
namespace Think\Database;
use Think\Target;
class PDOAdapter implements Target{
protected $conn; //用于存放连接数据库句柄
//实现连接方法
public function connect($host, $user, $passwd, $dbname) {
$conn = new \PDO("mysql:host={$host}; dbname={$dbname}", $user, $passwd);
$this->conn = $conn;
}
//查询方法
public function query($sql) {
return $this->conn->query($sql);
}
//关闭方法
public function close() {
unset($this->conn);
}
}
统一的数据库类 Think/DataBase.php
<?php
namespace Think;
class DataBase implements Target{
protected $db; //存放数据库对象
//设置数据库类
public function __construct($type = '') {
$type = "\\Think\\Database\\".$type;
$this->db = new $type;
}
//链接数据库
public function connect($host, $user, $passwd, $dbname) {
$this->db->connect($host, $user, $passwd, $dbname);
}
//查询方法
public function query($sql) {
return $this->db->query($sql);
}
//关闭连接
public function close() {
$this->db->close();
}
}
自动加载 Think/Loder.php
<?php
namespace Think;
class Loder{
static function autoload($class){
require BASEDIR . '/' .str_replace('\\','/',$class) . '.php';
}
}
入口文件 index.php
<?php
define('BASEDIR',__DIR__);
include BASEDIR . '/Think/Loder.php';
spl_autoload_register('\\Think\\Loder::autoload');
$db = new \Think\DataBase('MySQLiAdapter');
$db->connect('localhost','root','123456','test');
print_r($db);
通过上面的代码,可以事先将不同的操作接口封装起来,对外显示成用户所期望的接口
通过上面的代码,可以事先将不同的操作接口封装起来,对外显示成用户所期望的接口
优点: 1、可以让任何两个没有关联的类一起运行。 2、提高了类的复用。 3、增加了类的透明度。 4、灵活性好。
缺点: 过多地使用适配器,会让系统非常零乱,不易整体进行把握。
使用场景:有动机地修改一个正常运行的系统的接口,这时应该考虑使用适配器模式。
注意事项:适配器不是在详细设计时添加的,而是解决正在服役的项目的问题。
上一篇 php设计模式之注册树模式
下一篇 php设置模式之策略模式