Active Record必须具有域逻辑吗?

时间:2013-09-04 01:37:33

标签: php oop design-patterns activerecord yii

我开始使用Yii框架,我看到了一些事情,并且不要让我睡觉。"在这里,我谈谈我对Yii用户如何使用Active Record的怀疑。

我看到很多人直接在Active Record中添加应用程序的业务规则,这与Gii生成的相同。我深信这是对积极记录和违反SRP的错误解释。

  

Early on, SRP is easier to apply. ActiveRecord classes handle persistence, associations and not much else. But bit-by-bit, they grow. Objects that are inherently responsible for persistence become the de facto owner of all business logic as well. And a year or two later you have a User class with over 500 lines of code, and hundreds of methods in it’s public interface. Callback hell ensues.

当我和一些人谈论它时,我的观点受到了批评。但当被问到:

当您需要通过Gii重新生成充满业务规则的Active Record时,您会做什么?改写?复制和粘贴?那太好了,恭喜!

得到答案,只有沉默。

所以,我:

为了达到更好的架构,我目前正在做的是在文件夹/ ar中生成Active Records。在/ models文件夹中添加域模型。

顺便说一句,域模型是谁拥有业务规则,是使用Active Records持久化和检索数据的域模型,这就是数据模型。

您如何看待这种方法? 如果我在某个地方出错,请在严厉批评之前告诉我为什么。

2 个答案:

答案 0 :(得分:1)

Active Record的定义,据Martin Fowler说:

  

对象包含数据和行为。大部分数据都是持久性的,需要存储在数据库中。 Active Record使用最明显的方法,将数据访问逻辑放在域对象中。这样,所有人都知道如何在数据库中读取和写入数据。

当您分离数据和行为时,您不再拥有活动记录。两个常见的相关模式是Data Mapper和Table / Row Gateway(这一个与RDBMS相关)。

再一次,福勒说:

  

Data Mapper是一个软件层,用于将内存中对象与数据库分开。它的职责是在两者之间传输数据,并将它们彼此隔离。使用Data Mapper,即使存在数据库,内存中的对象也不需要知道;他们不需要SQL接口代码,当然也不需要了解数据库模式。

再次:

  

Table Data Gateway保存用于访问单个表或视图的所有SQL:选择,插入,更新和删除。其他代码调用其方法与数据库进行所有交互。

     

行数据网关为您提供与记录结构中的记录完全相同但可以使用编程语言的常规机制访问的对象。数据源访问的所有细节都隐藏在此界面后面。

数据映射器通常与存储无关,映射器从存储中恢复数据并创建映射对象(普通旧对象)。映射的对象完全不知道存储在其他地方。

正如我所说,TDG / RDG与关系表更加内向相关。 TDG对象表示表的结构并实现所有常见操作。 RGD对象包含与表的一行相关的数据。与Data Mapper的映射对象不同,RDG对象有良知它是整体的一部分,因为它引用了它的容器TDG。

答案 1 :(得分:1)

本文的一些评论非常有帮助: http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/

特别是,当你需要更多时,你的模型应该从一个严格的“胖模型”设置中成长的想法似乎是非常明智的。

您现在遇到问题还是主要是提前计划?这可能很难提前规划,可能只需要重构......

修改

关于moveUserToGroup(在下面的评论中),我可以看到这可能会让您感到烦恼。在我考虑您的问题时发现这一点:https://gist.github.com/justinko/2838490您可能用于moveUserToGroup的等效设置将是CFormModel子类。它将使您能够进行验证等,但可能更具体到您要处理的内容(并使用多个AR对象来实现您的目标,而不仅仅是一个)。

我经常使用CFormModel来处理具有多个AR对象或表单的表单,我想做其他事情。

听起来这可能就是你所追求的。更多细节在这里: http://www.yiiframework.com/doc/guide/1.1/en/form.overview