將一個類的介面轉換為客戶期望的另一介面,使原本不兼容的類能夠協同工作。通俗說:統一異構介面為標準 API。
| 角色 | 說明 | 本例對應 |
|---|---|---|
| Target(目標介面) | 客戶期望的標準介面 | IDatabase |
| Adaptee(被適配者) | 現有異構實現 | mysql_*、pg_* 等原生擴展函數 |
| Adapter(適配器) | 實現 Target,內部委託 Adaptee | MysqlAdapter、PostgresqlAdapter |
<?php
// Target:統一標準介面
interface IDatabase {
public function connect(string $host, string $user, string $pass, string $db);
public function query(string $sql): array;
public function close();
}
// Adapter:MySQL 適配器
class MysqlAdapter implements IDatabase {
private $conn;
public function connect($host, $user, $pass, $db) {
$this->conn = mysqli_connect($host, $user, $pass, $db);
if (!$this->conn) throw new RuntimeException(mysqli_connect_error());
mysqli_set_charset($this->conn, 'utf8mb4');
}
public function query($sql) {
$res = mysqli_query($this->conn, $sql);
if (!$res) throw new RuntimeException(mysqli_error($this->conn));
return mysqli_fetch_all($res, MYSQLI_ASSOC);
}
public function close() { mysqli_close($this->conn); }
}
// Adapter:PostgreSQL 適配器
class PostgresqlAdapter implements IDatabase {
private $conn;
public function connect($host, $user, $pass, $db) {
$dsn = "host=$host dbname=$db user=$user password=$pass";
$this->conn = pg_connect($dsn);
if (!$this->conn) throw new RuntimeException(pg_last_error());
}
public function query($sql) {
$res = pg_query($this->conn, $sql);
if (!$res) throw new RuntimeException(pg_last_error());
return pg_fetch_all($res) ?: [];
}
public function close() { pg_close($this->conn); }
}
// 客戶端:僅依賴 IDatabase
function getUserList(IDatabase $db, int $limit = 10): array {
return $db->query("SELECT * FROM users LIMIT $limit");
}
// 使用:配置驅動切換實現
$driver = $_ENV['DB_DRIVER'] ?? 'mysql';
$adapter = match ($driver) {
'mysql' => new MysqlAdapter(),
'postgresql' => new PostgresqlAdapter(),
default => throw new InvalidArgumentException("Unknown driver: $driver"),
};
$adapter->connect('localhost', 'user', 'pass', 'app_db');
$users = getUserList($adapter);
$adapter->close();
print_r($users);
適配器模式是「介面導向程式設計」的經典落地,**不要重複造輪子**——優先採用社區標準介面(PSR 系列),專注業務邏輯創新。