前言
对于适配器其实很常见, 比如生活中的笔记本电脑的充电器, 他的作用就是将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数据库, 新功能能够抽象类本身全部实现, 也可以考虑扩展类接口来实现该功能.