是否需要在模型中持久化数据以便在方法中使用


Is there a need to persist data in model for use in methods?

在我的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变量以继续处理,第二个方法则不然,因为它更有可能引发异常。我推荐第一种方法,而不是第二种。