前言
對於適配器其實很常見, 比如生活中的筆記本電腦的充電器, 他的作用就是將220v的電壓轉換成19v的電壓, 提供給筆記本來使用, 電這個抽象類有提供能源的功能, 但是不同的用電器具有不同的電壓屬性. 所以需要一個轉接器. 這個轉接器就是適配器策略的來源.
遇到的問題
我們在寫代碼的時候, 經常會遇到這麼個情況, 某一個類只需小小的改動一下就能實現另一個類的功能, 比如 redis 和 mysql, 在使用redis的時候, 通常我們把它當做noSql來使用, 當redis 無法使用的時候, 或者不便於安裝的時候, 其實mysql 也可以臨時充當noSql 來使用. 這個時候 如果硬加塞一個 noSql的功能模塊給來實現redis 代碼就會很凌亂.
代碼實例
針對以上的情況我們如果來優雅的實現這個功能呢.
interface Db {
public function connect(): bool;
public function close(): void;
}
class MysqlDb implemenets Db {
public function connect(): bool {
// todo
return true;
}
public function close(): void {
// todo
}
}
interface NoSqlAdapter {
public function save(string $name, string $value): bool;
public function get(string $name): string;
}
class MysqlNoSqlAdapter implements NoSqlAdapter {
public MysqlDb $mysqlDb;
public function __construct(MysqlDb $mysql) {
$this->mysqlDb = $mysql;
}
public function save(string $name, string $value): bool {
// todo
return true;
}
public function get(string $value): string {
$this->msqlDb->connect();
// .... todo
$this->mySqlDb->close();
return 'value';
}
}
// 使用
(new MysqlNoSqlAdapter(new MysqlDb()))->get('name');
使用的時機與思考
當往期的類具備現代類的特徵, 符合稍加改動就能完美勝任現有模式的類, 可以考慮該模式. 當該類是抽象類的時候, 適配器模式可以對特定的具體類施加新功能, 如果抽象類本身都具備改造的特性, 比如例子中 也可以改造oricle數據庫, 新功能能夠抽象類本身全部實現, 也可以考慮擴展類接口來實現該功能.