【问题标题】:Can a Simple Model just Extend Zend_Db_Row (essentially Active Record)?一个简单的模型可以扩展 Zend_Db_Row(本质上是 Active Record)吗?
【发布时间】:2011-02-18 18:30:03
【问题描述】:

我知道领域模型和数据映射器是 OOP 势利小人的选择(以互补的方式使用“势利小人”,Martin Fowler 称自己为其中之一) - 然而,即使是 Fowler says in POEAA that

“Active Record 是不太复杂的领域逻辑的不错选择......”

我有一个简单的产品和发票域模型,没有太多要建模的表/对象/概念,而且关系也没有那么复杂。那么,这对 Active Record 来说是一个很好的用例吗?

Fowler 还指出 Active Record 类似于 Row Data Gateway,不同之处在于 Active Record 具有域逻辑。

假设这是一个有效的 Active Record 用例,并且由于 Zend 提供了 Row Data Gateway,扩展这些对象的智能解决方案(而不是简单地添加表名)似乎是使用以下方法创建 Active Record 对象的好方法Zend 框架。确实,that concept is discussed in this SO answer这是在 Zend 框架内实现 Active Record 的可接受方式吗?

当然,这个问题最受欢迎的答案是 one by Bill Karwin(他曾参与 Zend 的 Db 实现),建议 不要 以这种方式使用 Zend_Db_TableZend_Db_Row(至少我就是这样阅读)。

如果有问题的域模型变得更加复杂,我完全接受想要迁移到 Data Mapper 解决方案。我查看了各种 ORM/DataMapper(不仅仅是所讨论的域模型,最近还阅读了有关 OOP 设计模式的更多信息),对于某些事情来说,它们似乎真的太多了。

【问题讨论】:

    标签: php oop zend-framework activerecord datamapper


    【解决方案1】:

    对于一些简单的事情,扩展 Zend_Db_Table 包的模型是一个不错的选择。我用过很多次都非常成功,它看起来像这样:

    class App_Model_Users extends Mojito_Model_Abstract
    {    
        protected $_dbTableClass='App_Model_Users_Table';
    
        public function getByEmail($email)
        {
            $Select=$this->_DbTable->select()->where(new Zend_Db_Expr('LOWER(usrEmail)=?'),strtolower($email));
            $User=$this->_DbTable->fetchRow($Select);
            return $this->verifyRow($User);
        }
    
    }
    
    class App_Model_Users_Table extends Zend_Db_Table_Abstract
    {
        protected $_name = 'users';
        protected $_primary = 'user_id';
        protected $_rowsetClass = 'App_Model_Users_Rowset';
        protected $_rowClass = 'App_Model_Users_Row';
    }
    
    class App_Model_Users_Rowset extends Zend_Db_Table_Rowset_Abstract
    {
    }
    
    class App_Model_Users_Row extends Zend_Db_Table_Row_Abstract
    {
        protected function _insert()
        {
            // pre instert logic such as:
            $this->password = sha1($this->password);
        }
    
        protected function _postInsert()
        {
            // email user a welcome
        }
    
        protected function _postDelete()
        {
            // delete related files such as avatar
            // can also get a rowset of related many's to delete
        }
    
    }
    

    您可以在这里阅读更多内容http://talentedmrjones.posterous.com/simple-models-with-zenddbtable

    当然,您可能不需要或不想要我从 Mojito_Model_Abstract 扩展的所有功能,但我相信您了解正在发生的事情的要点。

    【讨论】:

    • @Tim 抱歉,我完全误读了您的问题!我现在看到是关于是使用 ActiveRecord 还是 TDG,而不是问如何实现 Zend_Db_Table,我相信你已经掌握了。
    • 没问题,您的示例有助于验证我的想法。我很感激。
    【解决方案2】:

    我已经这样做了,并且对结果完全满意。

    IMO,您必须 永远不要做的唯一一件事就是在您的控制器和视图/视图助手中使用父方法。即,始终在应用程序其余部分使用的扩展 Zend_Db_Table_Abstract 和 Zend_Db_Table_Abstract_Row 类中编写自己的方法。如果需要,您可以选择将 TDG/AR 换成更复杂的东西。

    【讨论】:

    • 完全同意不直接使用底层数据访问。你发现什么有效?完整的数据映射器?
    • 如果可以避免的话,我很少做复杂的事情:) 对于简单的东西,我将创建class News extends Zend_Db_Table_Abstract 和类class NewsItem extends Zend_Db_Table_Row_Abstract。我发现 setFromArray() 可以很好地填充 NewsItem 并且 save() 也可以。我在 News 中创建了新的 fetch 方法。
    • 哇,完全误读了你的第一行——我在“完全满意”之前写了一个“从未”。因此,在您已经回答之后,“您发现什么有效”。感谢您的洞察力。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多