【发布时间】:2014-02-14 17:15:49
【问题描述】:
这是关于缓存代理设计模式的问题。
是否可以使用 PHP 创建一个动态代理缓存实现来自动将缓存行为添加到任何对象?
这是一个例子
class User
{
public function load($login)
{
// Load user from db
}
public function getBillingRecords()
{
// a very heavy request
}
public function computeStatistics()
{
// a very heavy computing
}
}
class Report
{
protected $_user = null;
public function __construct(User $user)
{
$this->_user = $user;
}
public function generate()
{
$billing = $this->_user->getBillingRecords();
$stats = $this->_user->computeStatistics();
/*
...
Some rendering, and additionnal processing code
...
*/
}
}
您会注意到报告将使用来自用户的一些重载方法。
现在我想添加一个缓存系统。 与其设计经典的缓存系统,我只是想知道是否可以使用这种用法以代理设计模式实现缓存系统:
<?php
$cache = new Cache(new Memcache(...));
// This line will create an object User (or from a child class of User ex: UserProxy)
// each call to a method specified in 3rd argument will use the configured cache system in 2
$user = ProxyCache::create("User", $cache, array('getBillingRecords', 'computeStatistics'));
$user->load('johndoe');
// user is an instance of User (or a child class) so the contract is respected
$report = new report($user)
$report->generate(); // long execution time
$report->generate(); // quick execution time (using cache)
$report->generate(); // quick execution time (using cache)
对代理方法的每次调用都会运行类似:
<?php
$key = $this->_getCacheKey();
if ($this->_cache->exists($key) == false)
{
$records = $this->_originalObject->getBillingRecords();
$this->_cache->save($key, $records);
}
return $this->_cache->get($key);
你认为这是我们可以用 PHP 做的事情吗?你知道它是否是标准模式吗?你将如何实现它?
这需要
- 动态实现原始对象的新子类
- 用缓存的方法替换指定的原始方法
- 实例化一个新的对象
我认为 PHPUnit 在 Mock 系统中做了类似的事情......
【问题讨论】:
-
PHPUNIT 使用一些模板和一个 eval 来做到这一点......所以它显然不适合 prdo github.com/sebastianbergmann/phpunit-mock-objects/blob/master/…
-
我来晚了,但是当我在寻找同样的问题时,这里有一个可能的解决方案的详细帖子:stackoverflow.com/questions/17485854/…
标签: oop caching design-patterns proxy