使用PHP 5.3中的Decorator模式进行DRY

时间:2013-09-30 22:19:00

标签: php design-patterns

我正在尝试编写一个Decorator类型类,它将结果缓存到任何内容(从memecache开始)。每种方法都需要检查缓存$ this-> cache-> get($ key),如果没有找到,请调用真实方法$ this-> real-> getExpensiveInfo01($ param1,$ param2,$ param3)然后设置$ this-> cache-> set($ key,$ expensiveInfo)。所以现在每个方法都有这个样板代码;

class ExpensiveCache implements ExpensiveInterface
{
  public function getExpensiveInfo01($param1, $param2, $param3)
  {
     $key = __FUNCTION__ . $param1 . $param2 . $param3;
     $rtn = $this->cache->get($key);
     if ($rtn === false) {
        $rtn = $this->expensive->getExpensiveInfo01($param1, $param2, $param3);
        $cacheStatus = $this->cache->set($key, $rtn);
    }
    return $rtn;
  }
  public function getExpensiveInfo02($param1, $param2)
  {
     $key = __FUNCTION__ . $param1 . $param2;
     $rtn = $this->cache->get($key);
     if ($rtn === false) {
        $rtn = $this->expensive->getExpensiveInfo02($param1, $param2);
        $cacheStatus = $this->cache->set($key, $rtn);
    }
    return $rtn;
  }
  public function getExpensiveInfo03($param1, $param2)
  {
     $key = __FUNCTION__ . $param1 . $param2;
     $rtn = $this->cache->get($key);
     if ($rtn === false) {
        $rtn = $this->expensive->getExpensiveInfo03($param1, $param2);
        $cacheStatus = $this->cache->set($key, $rtn);
    }
    return $rtn;
  }
}

无论如何在PHP5.3(该死的CentOS)中将锅炉板代码减少为一个私有方法调用。

2 个答案:

答案 0 :(得分:1)

不公开,但公开__call

class ExpensiveCache implements ExpensiveInterface {
    public function __call($name, $arguments) {
        $key = $name.implode('', $arguments);
        $rtn = $this->cache->get($key);
        if ($rtn === false) {
            $rtn = call_user_func_array(array($this->expensive, $name), $arguments);
            $cacheStatus = $this->cache->set($key, $rtn);
        }
        return $rtn;
    }
}

(如果$ this-> expensive-> $ name可以调用,可以添加一些支票)

答案 1 :(得分:0)

也许是这样的:

private function getCacheKey(array $args)
{
    return implode('', $args);
}

private function getExpensiveInfo()
{
    $args = func_get_args();
    $key = $this->getCacheKey($args);
    if (($value = $this->cache->get($key)) === false) {
        $value = call_user_func_array(array($this->expensive, __FUNCTION__), $args);
        $this->cache->set($key, $value);
    }

    return $value;
}