Adapter 适配器模式,使原本由于接口不兼容而不能一起工作的那些类可以一起工作
例如之前是使用 Redis 作缓存,现在想改为文件系统缓存,两者的使用方式天差地别
旧的 Redis 缓存如下:
class Cache
{
private $redis;
public function __construct(\Redis $redis)
{
$this->redis = $redis;
}
public function set($key, $value, $ttl)
{
$this->redis->set($key, $value);
$this->redis->expire($key, $ttl);
}
public function get($key)
{
return $this->redis->get($key);
}
}
新的文件系统如下:
class FileSystem
{
private $basePath;
public function __construct($basePath)
{
$this->basePath = $basePath;
}
public function update($fileName, $value)
{
if (!file_exists(dir($this->basePath . "/$fileName"))) {
mkdir(dir($this->basePath . "/$fileName"), 0777, true);
}
file_get_contents($this->basePath . "/$fileName", $value);
}
public function getContent($fileName)
{
return file_get_contents($this->basePath . "/$fileName");
}
public function unlink($fileName)
{
unlink($this->basePath . "/$fileName");
}
}
现在想改的话要一个一个方法去搜去改,非常非常麻烦。我们可以使用适配器模式,让文件系统也支持原有的方法:
interface CacheInterface
{
public function get($key);
public function set($key, $value, $ttl);
}
class FileSystemAdapter implements CacheInterface
{
private $fileSystem;
public function __construct(FileSystem $fileSystem)
{
$this->fileSystem = $fileSystem;
}
public function get($key)
{
$valueAry = $this->fileSystem->getContent($key);
$value = null;
if (!empty($valueAry) && $valueAry = json_decode($valueAry, true)) {
if (isset($valueAry['expireAt']) && isset($valueAry['value'])) {
if ($valueAry['expireAt'] > time()) {
$value = $valueAry['value'];
} else {
$this->fileSystem->unlink($key);
}
}
}
return $value;
}
public function set($key, $value, $ttl)
{
$valueAry = [
'value' => $value,
'expireAt' => time() + $ttl,
];
$this->fileSystem->update($key, json_encode($valueAry));
}
}
下面是两种方式的实现,可以看到在使用上完全一致:
//Redis方式
$redis = new Redis();
$redis->connect('','');
$cache = new Cache($redis);
$cache->set('stock_price_300033', '200', 60);
$stockPrice = $cache->get('stock_price_300033');
//文件系统方式
$cache = new FileSystemAdapter(new FileSystem('/data/www/data'));
$cache->set('stock_price_300033', '201', 60);
$stockPrice = $ache->get('stock_price_300033');