適配器模式
將某個(gè)對(duì)象的接口適配為另一個(gè)對(duì)象所期望的接口,例如某個(gè)操作數(shù)據(jù)庫的有多種不同的數(shù)據(jù)庫操作方法,通過適配器統(tǒng)一成一個(gè)接口
目錄結(jié)構(gòu)
|adpater #項(xiàng)目根目錄
|--Think #核心類庫
|----Database #數(shù)據(jù)庫操作類
|------MySQLAdapter.php #MySQL類
|------MySQLiAdapter.php #MySQLi類
|------PDOAdapter.php #PDO類
|----Loder.php #自動(dòng)加載類
|----Target.php #數(shù)據(jù)庫適配器接口類
|----DataBase.php #統(tǒng)一的數(shù)據(jù)庫類
|--index.php #單一的入口文件
代碼實(shí)現(xiàn)
數(shù)據(jù)庫適配器接口類 Think/Target.php
<?php
namespace Think;
//定義一個(gè)數(shù)據(jù)庫的適配器接口類
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; //用于存放連接數(shù)據(jù)庫句柄
//實(shí)現(xiàn)連接方法
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;
}
//關(guān)閉方法
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; //用于存放連接數(shù)據(jù)庫句柄
//實(shí)現(xiàn)連接方法
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;
}
//關(guān)閉方法
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; //用于存放連接數(shù)據(jù)庫句柄
//實(shí)現(xiàn)連接方法
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);
}
//關(guān)閉方法
public function close() {
unset($this->conn);
}
}
統(tǒng)一的數(shù)據(jù)庫類 Think/DataBase.php
<?php
namespace Think;
class DataBase implements Target{
protected $db; //存放數(shù)據(jù)庫對(duì)象
//設(shè)置數(shù)據(jù)庫類
public function __construct($type = '') {
$type = "\\Think\\Database\\".$type;
$this->db = new $type;
}
//鏈接數(shù)據(jù)庫
public function connect($host, $user, $passwd, $dbname) {
$this->db->connect($host, $user, $passwd, $dbname);
}
//查詢方法
public function query($sql) {
return $this->db->query($sql);
}
//關(guān)閉連接
public function close() {
$this->db->close();
}
}
自動(dòng)加載 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);
通過上面的代碼,可以事先將不同的操作接口封裝起來,對(duì)外顯示成用戶所期望的接口
通過上面的代碼,可以事先將不同的操作接口封裝起來,對(duì)外顯示成用戶所期望的接口
優(yōu)點(diǎn): 1、可以讓任何兩個(gè)沒有關(guān)聯(lián)的類一起運(yùn)行。 2、提高了類的復(fù)用。 3、增加了類的透明度。 4、靈活性好。
缺點(diǎn): 過多地使用適配器,會(huì)讓系統(tǒng)非常零亂,不易整體進(jìn)行把握。
使用場(chǎng)景:有動(dòng)機(jī)地修改一個(gè)正常運(yùn)行的系統(tǒng)的接口,這時(shí)應(yīng)該考慮使用適配器模式。
注意事項(xiàng):適配器不是在詳細(xì)設(shè)計(jì)時(shí)添加的,而是解決正在服役的項(xiàng)目的問題。