5

所以我只是好奇这个:

DataMapper 为其模型使用 mixin

class Post
  include DataMapper::Resource

虽然活动记录使用继承

class Post < ActiveRecord::Base

有谁知道为什么 DataMapper 选择这样做(或者为什么 AR 选择不这样做)?

4

5 回答 5

5

它允许您从另一个不是 DM 类的类继承。

它还允许动态地将 DM 功能添加到类中。这是我现在正在处理的模块中的一个类方法:

def datamapper_class
  klass = self.dup
  klass.send(:include, DataMapper::Resource)
  klass.storage_names[:default] = @table_name
  klass.property(:id, DataMapper::Types::Serial)
  klass.property(:created_at, DateTime, :nullable => false)
  klass.property(:updated_at, DateTime, :nullable => false)
  columns_with_types { |n, t| klass.property(n, t, :field => n.to_s) }
  klass
end

这让我可以使用 SAXMachine 类(非常轻量级)并将其动态转换为 Datamapper 类,并用它来做 DataMappery 的事情。你甚至可以把它放到一个对象的单例类中。

我喜欢想象当我从 XML 导入 100K 对象时,这会降低我的内存占用(我不使用 DM 进行大量导入),并且只在需要时混合更复杂的数据库函数

于 2009-07-24T23:16:09.573 回答
4

DataMapper 模式旨在提供一个允许域对象模型与模式不同的层。ActiveRecord 统一了对象模型和关系数据库结构。

根据马丁·福勒

对象和关系数据库具有不同的数据结构化机制。对象的许多部分,例如集合和继承,在关系数据库中不存在。当您构建具有大量业务逻辑的对象模型时,使用这些机制来更好地组织数据和随之而来的行为是很有价值的。这样做会导致不同的模式;也就是说,对象模式和关系模式不匹配。

您仍然需要在两个模式之间传输数据,而这种数据传输本身就变得很复杂。如果内存中的对象知道关系数据库结构,那么其中一个对象的更改往往会波及另一个对象。

数据映射器是将内存中的对象与数据库分开的软件层。它的职责是在两者之间传输数据,并将它们彼此隔离。使用 Data Mapper,内存中的对象甚至不需要知道是否存在数据库;他们不需要 SQL 接口代码,当然也不需要数据库模式的知识。(数据库模式总是不知道使用它的对象。)由于它是 Mapper (473) 的一种形式,因此 Data Mapper 本身对于领域层来说甚至是未知的。

于 2009-12-08T21:49:11.317 回答
3

我认为这个想法是 ActiveRecord 认为数据库支持的方面是模型类的关键特性,因此它继承了该行为。DataMapper 看起来它认为支持数据库只是可以添加到类中的类的一个方面。

这是我的猜测。Yehuda Katz 可以明确地告诉你。

于 2009-07-24T21:45:07.387 回答
0

这确实是选择继承与组合的问题。

我个人喜欢组合,因为它似乎是一种更自然的构造类和对象的方式。

作文使您可以更好地控制要包含在课堂上的行为。至于继承,你要么一无所有,要么一无所有。组合允许你挑选你想要的行为。

于 2009-08-26T17:02:32.987 回答
0

ActiveRecord 实际上不应该使用继承,而是包含一个模块来将行为(主要是持久性)添加到模型/类中。ActiveRecord 只是使用了错误的范例!

出于同样的原因,我非常喜欢 MongoId 而不是 MongoMapper,因为它让开发人员有机会使用继承作为对问题域中有意义的东西进行建模的方式。

遗憾的是,Rails 社区中几乎没有人按照应有的方式使用“Ruby 继承”——定义类层次结构,而不仅仅是添加行为。

于 2011-04-04T03:26:44.657 回答