<?php
/* 重构该段代码
问题:2个find函数,除了两行语句不一样,其他地方全部相同
业务:object信息有2种查询
1. 根据提交objectkey field,查询object信息
2. 根据objectid来查询objectkey&objectsecret
object信息存储于mysql中,因为涉及在一次请求中,多次重复查询,因此,此处使用了2类cache
MemoryCache是服务器内存cache
RedisCache是Redis服务器cache
首先查询是否在MemoryCache,不在查询RedisCache;RedisCache查询,在插入MemoryCache;
不再查询mysql,并将查询结果插入两种缓存。
*/
class Object
{
public function findObjectByObjectkey($objectkey, $field = null)
{
$result = null;
$key = $this->adaptKey($objectkey);
//加入本地内存的缓存,先查询本地缓存
if($result = MemoryCache::getInstance()->get($key)) {
return $this->dealRet($result, $field);
}
//在查询redis
if($result = RedisCache::getInstance()->get($key)){
MemoryCache::getInstance()->set( $key, $result);
return $this->dealRet($result, $field);
}
// 查mysql
$object = new ObjectDao();
if ($result = $object->findByObjectkey($objectkey)) {
RedisCache::getInstance()->set($key, $result);
MemoryCache::getInstance()->set( $key, $result);
}
return $this->dealRet($result, $field);
}
public function findObjectByObjectid($id)
{
$result = null;
$key = $this->adaptId($id); // 不一致
if($result = MemoryCache::getInstance()->get($key)) {
return $this->dealRet($result, null);
}
if($result = RedisCache::getInstance()->get($key)){
MemoryCache::getInstance()->set( $key, $result);
return $this->dealRet($result, null);
}
$object = new ObjectDao();
if ($result = $object->findById($id)) { //不一致
RedisCache::getInstance()->set($key, $result);
MemoryCache::getInstance()->set( $key, $result);
}
return $this->dealRet($result, null);
}
private function dealRet($ret, $field)
{
}
private function adaptKey($key)
{
return "keyInfo:{$key}";
}
private function adaptId($id)
{
return "idInfo:{$id}";
}
}
重构:
<?php
/*
* refactor one.
*
*/
class AbstractDecorator
{
$decorator = null;
public __construct(AbstractDecorator $decorator=null)
{
$this->decorator = empty($decorator) ? new NullDecorator() : $decorator;
}
public abstract function find($key, $field = null);
public abstract function setCache($key, $value);
}
class NullDecorator extends AbstractDecorator
{
public function find($key, $field = null){
return null;
}
public function setCache($key, $value){
}
}
class MemoryCacheDecorator extends AbstractDecorator
{
public function find($key)
{
return ($ret = MemoryCache::getInstance()->get($key)) ? ($ret) : (($ret=$decorator->find($key))&&($this->setCache($key, $ret)) ? $ret : null);
}
public function setCache($key, $value){
return MemoryCache::getInstance()->set($key, $value);
}
}
class RedisCacheDecorator extends AbstractDecorator
{
public function find($key)
{
return ($ret=RedisCache::getInstance()->get($key)) ? ($ret) : ( ($ret=$decorator->find($key))&&($this->setCache($key, $ret)) ? $ret : null );
}
public function setCache($key, $value){
RedisCache::getInstance()->set($key, $value);
}
}
class Refacted1App
{
public function findAppByAppkey($appkey, $field = null)
{
$result = null;
$key = $this->getKeyPrefix($appkey);
$cache = new MemoryCacheDecorator(new RedisCacheDecorator());
if($ret = $cache->find($appkey)){
return $this->dealRet($ret, $field);
}
// 查mysql
$app = new AppDao();
if ($result = $app->findByAppkey($appkey)) {
$cache->set($key, $result);
}
return $this->dealRet($result, $field);
}
public function findAppByAppid($id)
{
$result = null;
$key = $this->getKeyPrefix($appkey);
$cache = new MemoryCacheDecorator(new RedisCacheDecorator());
if($ret = $cache->find($appkey)){
return $this->dealRet($ret, $field);
}
$app = new AppDao();
if ($result = $app->findById($id)) {
$cache->set($key, $result);
}
return $this->dealRet($result, null);
}
private function dealRet($ret, $field)
{
}
private function getKeyPrefix($key)
{
return __CLASS__."keyInfo:{$key}";
}
private function getIdPrefix($id)
{
return __CLASS__."idInfo:{$id}";
}
}
class Refacted2App
{
private function find($key, $field, $prefix, $mysqlfind)
{
$result = null;
$key = $prefix($appkey);
$cache = new RedisCacheDecorator(new MemoryCacheDecorator());
if($ret = $cache->find($appkey)){
return $this->dealRet($ret, $field);
}
$app = new AppDao();
if ($result = $mysqlfind($id)) {
$cache->set($key, $result);
}
return $this->dealRet($result, null);
}
public function findAppByAppkey($appkey, $field)
{
$prefix = function()
{
return $this->getKeyPrefix($appkey);
}
$mysqlfind = function()
{
$app = new AppDao();
return $app->findAppByAppkey();
}
return $this->find($appkey, $field, $prefix, $mysqlfind);
}
}