我的回答又长又迟,甚至不完整,但很好地解释了为什么我讨厌这种模式、观点甚至一些情绪:
1) 短版:Active Record 在数据库和应用程序代码之间创建一个“强绑定”的“thin layer”。这没有解决任何逻辑问题,没有任何问题,根本没有问题。恕我直言,它不提供任何值,除了一些 语法糖 供程序员使用(然后可能使用“对象语法”来访问关系数据库中存在的一些数据)。为程序员创造一些舒适感的努力应该(恕我直言......)更好地投资于低级数据库访问工具,例如simple,easy,plain hash_map get_record( string id_value, string table_name, string id_column_name="id" ) 和类似方法的一些变体(当然,概念和优雅因使用的语言而有很大差异)。
2) 长版本:在我对事物进行“概念控制”的任何数据库驱动项目中,我避免使用 AR,这很好。我通常构建一个分层架构(你迟早会把你的软件分层,至少在大中型项目中是这样):
A1) 数据库本身、表、关系,如果 DBMS 允许的话,甚至是一些逻辑(MySQL 现在也成熟了)
A2) 很多时候,不仅仅是一个数据存储:文件系统(数据库中的 blob 并不总是一个好的决定......),遗留系统(想象自己“如何”访问它们,可能有很多种类。 . 但这不是重点...)
B) 数据库访问层(在这个级别,工具方法,帮助轻松访问数据库中的数据非常受欢迎,但 AR 在这里没有提供任何价值,除了一些语法糖)
C) 应用对象层:“应用对象”有时是数据库中表格的简单行,但大多数时候它们无论如何都是复合对象,并且附加了一些更高的逻辑,所以要花费时间在这个级别的 AR 对象中显然是无用的,浪费了宝贵的编码人员时间,因为这些对象的“真正价值”,“更高的逻辑”需要在 AR 对象之上实现,无论如何 - 有和没有 AR !而且,例如,为什么要抽象“日志条目对象”?应用程序逻辑代码编写它们,但它应该具有更新或删除它们的能力吗?听起来很傻,App::Log("I am a log message") 比le=new LogEntry(); le.time=now(); le.text="I am a log message"; le.Insert(); 更容易使用。例如:在您的应用程序的日志视图中使用“日志条目对象”将适用于 100、1000 甚至 10000 条日志行,但迟早您将不得不优化 - 我敢打赌,在大多数情况下,您只会在你的应用程序逻辑中使用那个漂亮的小 SQL SELECT 语句(这完全打破了 AR 的想法......),而不是将那个小语句包装在刚性固定的 AR 想法框架中,并使用大量代码包装和隐藏它。您浪费在编写和/或构建 AR 代码上的时间本可以投入到一个更智能的界面上,用于阅读日志条目列表(很多很多方面,没有限制)。编码人员应该敢于发明新的抽象以实现适合预期应用程序的应用程序逻辑,并且不要愚蠢地重新实现愚蠢的模式,这听起来不错! p>
D) 应用程序逻辑 - 实现交互对象以及创建、删除和列出(!)应用程序逻辑对象的逻辑(不,这些任务很少应该锚定在应用程序逻辑对象本身:纸上是否你的办公桌会告诉你办公室里所有其他工作表的名称和位置?忘记列出对象的“静态”方法,那是愚蠢的,这是为了让人类的思维方式适应 [some-not-all-AR-框架式-]AR 思维)
E) 用户界面 - 好吧,我将在以下几行中写下非常非常主观的内容,但根据我的经验,基于 AR 构建的项目通常会忽略应用程序的 UI 部分 - 时间被浪费在了创建模糊的抽象。最后,这样的应用程序浪费了编码人员的大量时间,感觉就像是编码人员为编码人员提供的应用程序,内部和外部都倾向于技术。编码员感觉很好(努力工作终于完成,一切都完成并正确,根据纸上的概念......),客户“只需要了解它需要那样”,因为那是“专业”......好吧,对不起,我离题了;-)
好吧,诚然,这一切都是主观的,但这是我的经验(Ruby on Rails 除外,它可能会有所不同,而且我对这种方法的实践经验为零)。
在付费项目中,我经常听到需要从创建一些“活动记录”对象作为更高级别应用程序逻辑的构建块开始。根据我的经验,这明显经常是客户(在大多数情况下是软件开发公司)没有好的概念、大视野、对产品应该做什么的概述的某种借口终于可以了。那些客户在僵化的框架中思考(“十年前的项目运行良好..”),他们可能会充实实体,他们可能会定义实体关系,他们可能会分解数据关系并定义基本的应用程序逻辑,但随后他们就停止了把它交给你,认为这就是你所需要的......他们往往缺乏完整的应用程序逻辑,用户界面,可用性等概念......他们缺乏大视野,他们缺乏对应用程序的热爱细节,他们希望你遵循 AR 的方式,因为.. 好吧,为什么,它在几年前的那个项目中起作用,它让人们忙碌而沉默?我不知道。但是“细节”将男人与男孩分开,或者..最初的广告口号是怎样的? ;-)
经过多年(十年积极开发经验),每当客户提到“活跃记录模式”时,我的警钟就会响起。我学会了尝试让他们回到那个重要的概念阶段,让他们三思而后行,尝试让他们展示他们的概念弱点,或者如果他们没有辨别力就完全避免他们(最后,你知道,一个还不知道自己想要什么的客户,甚至可能认为自己知道但不知道,或者试图免费将概念工作外化给我,这花费了我许多宝贵的时间、几天、几周和几个月的时间,生活是太短了……)。
所以,最后:这就是为什么我讨厌这种愚蠢的“主动记录模式”,我会并且会尽可能避免它。
编辑:我什至会称之为无模式。它不能解决任何问题(模式并不意味着创建语法糖)。它产生了许多问题:所有问题的根源(在此处的许多答案中都提到了......)是,它只是隐藏在模式接口后面的良好的旧的、开发良好且功能强大的 SQL定义极其有限。
这种模式用语法糖代替了灵活性!
想一想,AR 为你解决了哪些问题?