数据映射器(Data Mapper)比活动记录(Active Record)更为现代化的趋势吗?

41

我最近发现一些ORM宣布计划将其实现从Active Record迁移到Data Mapper。我对这个主题的知识非常有限。因此,向那些了解更多的人提出一个问题,是Data Mapper比Active Record更新吗?在Active Record运动开始时,它是否存在?这两者之间的关系如何?

最后,由于我不是数据库专业人员并且了解很少关于这个主题,所以我应该追随正在转向Data Mapper实现的ORM,作为编写软件的个人(而不是数据人员),我能从中获得什么好处?

2个回答

69

DataMapper并不是更加现代或更新的技术,而是更适合用于ORM。

人们改用DataMapper的主要原因是因为ActiveRecord并不是一个好的ORM。AR会将数据库表或视图的行包装起来,封装了对数据库的访问,并在这些数据上添加域逻辑。因此,按照定义,AR是数据库记录的1:1表示,特别适合进行简单的CRUD操作。

一些AR新增了获取相关数据的功能,这使人们认为AR是ORM。但它不是。ORM的目标是解决数据库结构和域对象之间的对象-关系阻抗不匹配问题。使用AR时,您没有解决这个阻抗不匹配的问题,因为AR代表着一个数据库行,而不是一个真正的OO设计。你把你的db布局和你的对象联系在了一起。然而,仍然可以应用一些对象-关系行为模式(例如延迟加载)。

另一个AR经常被批评的原因是它混淆了两个关注点:业务逻辑和db访问逻辑。这导致不必要的耦合,可能会在较大的应用程序中导致更少的可维护性和灵活性。两层之间没有隔离。耦合总是导致灵活性降低。

另一方面,DataMapper将数据在对象和数据库之间移动,同时使它们彼此独立并与映射器本身独立。虽然实现起来更加困难,但它允许您在应用程序中进行更加灵活的设计。您的域对象不再必须匹配db结构。DAL和领域层被解耦了。


22

虽然这篇文章已经8年了,但问题在2018年仍然是有效的。

Active Record是反模式,请注意。它会在代码和数据库之间产生非常紧密的耦合。对于小而简单的项目可能不是问题,但我强烈建议您避免在任何更大的项目中使用它。

良好的面向对象设计是分层的。输入层、服务层、存储库层、数据映射器和数据库-这只是一个简单的例子。您不应该将输入层与数据库混合在一起。如何做到这一点?例如,在Laravel中,您可以使用Validator规则来实现:

'email' => 'exists:staff,email'

它检查表staff中是否存在电子邮件。这是完全的OOP无意义。它将您的顶层与DB列名称联系在一起。我无法想象有任何更糟糕的OOP设计例子。

归根结底 - 如果你正在创建一个只有2-3个表格(如博客)的简单网站,Active Record可能不是问题。对于任何规模更大的项目,请使用Data Mapper,并注意IoC、SoC等OOP原则。


3
我强烈不同意将Active Record视作反模式。最终,一切都归结于开发人员在长期时间内的生产力。我曾使用过SQLAlchemy(一个数据映射器ORM)和Django ORM(一个Active Record ORM)。我使用Django ORM时更加高效,尽管我对它的经验较少。通常我不需要编写复杂的逻辑,只需要简单的CRUD查询。Django ORM使这变得轻松且易于阅读。此外,Django并不小。与Flask一起,它是Python中使用最广泛的Web框架之一。所以我可能不是唯一有这种感受的人。 - Martin Thoma
3
实施快捷方式和反模式总是以“在这种情况下会更简单”开始,但随着应用程序的增长,往往事与愿违。Laravel 的活动记录在多个层面上都存在问题。 - Peter Matisko
从我的经验来看,Active Record 更加高效。我正在处理一个大约有100个表的数据库。有时候你并不需要那么多的解耦,因为最终所有的表格都以某种方式相互关联,通常没有办法在不暴露应用程序其他部分功能的情况下使用少量功能。在这种情况下,过度设计似乎是更反模式的事情。它会极大地降低生产力。 - dzcpy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接