在我的ZF项目中,我有一个模型,它必须处理存储在Zend_Registry中的大型数组。数组从缓存(而不是从数据库)进入注册表。模型的不同方法可以在请求期间多次使用该数组。考虑到最佳实践和优化的性能,我不确定是否应该:
- 为其应用一个专用属性,并将其用于某种缓存
- 每次从注册表获取数组。
专用属性示例:
class Application_Model_Category {
private $_tree = null;
...
public function _getTree() {
if (!$this->_tree) {
$this->_tree = Zend_Registry::get('tree');
}
return $this->_tree;
...
public function methodOne() {
foreach ($this->_getTree() as $category) {
...
}
}
public function methodTwo() {
$tree = $this->_getTree();
foreach ($tree as $category) {
...
$count = count($tree);
}
}
...
}
从注册表中获取每次时间的示例:
class Application_Model_Category {
...
public function methodOne() {
foreach (Zend_Registry::get('tree') as $category) {
...
}
}
public function methodTwo() {
$tree = Zend_Registry::get('tree');
foreach ($tree as $category) {
...
$count = count($tree);
}
}
...
}
这些方法有什么不同吗(比如内存或cpu使用率)?还是第一种方法看起来更漂亮一点?
我肯定会选择第一个。如果有必要,将来更容易更改,并且它更好地封装了数据获取。(实际上,在那个句子中,第二件事是第一件事的原因。)
考虑一下:
如果以后你希望能够传递一个参数给构造函数,以允许重写从注册表中获取它的行为,该怎么办?如果您使用第一种方法,您只需要在一个地方更改代码。
同样,对于第一个选项,如果您扩展类,则子类不需要了解getTree的工作原理。对于第二种方式,它也将依赖于注册表。
基本上第一种方法略微降低了耦合,这是好的。
我不相信有任何性能问题,因为数组实际上并没有被复制,只是引用。
然而,为了清晰和测试,我将为树添加公共getter/setter。您的getter可以像现在这样从Zend_Registry
惰性加载,但至少允许一个公共setter更清楚地反映依赖性,并允许您使用模拟树进行测试。
显然,第一种方法会减慢处理速度,几乎可以忽略不计,但这完全取决于您要创建的功能。第一个方法确保存在_tree
变量以继续处理,第二个方法则不然,因为它更有可能引发异常。我推荐第一种方法,而不是第二种。