2009-07-24 13 views
5

así que estoy curioso acerca de esto:¿Por qué DataMapper usa mixins vs inheritance?

DataMapper utiliza un mixin para sus modelos

class Post 
    include DataMapper::Resource 

Mientras que activa a grabar utiliza la herencia

class Post < ActiveRecord::Base 

¿Alguien sabe por qué eligió hacer DataMapper de esa manera (o por qué AR eligió no hacerlo)?

Respuesta

3

Creo que la idea es que ActiveRecord considere que el aspecto respaldado por la base de datos es la característica clave de una clase de modelo, por lo que hereda ese comportamiento. DataMapper parece que considera que la base de datos respaldada solo es un aspecto de una clase que se puede agregar a una clase.

Esa es mi suposición. Yehuda Katz podría decirte definitivamente.

+0

Pensé que podría ser una razón puramente 'filosófica' - Veamos lo que otras personas dicen. – cloudhead

5

Le permite heredar de otra clase que no es una clase de DM.

También permite agregar las características de DM a una clase sobre la marcha. He aquí un método de clase de un módulo que estoy trabajando en este momento:

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 

Esto me permite tomar una clase SAXMachine (muy ligero) y convertirla en una clase DataMapper sobre la marcha, y hago DataMappery cosas con ella . Incluso podrías hacerlo a la clase singleton de un objeto.

Me gusta imaginar que esto reduce la huella de mi memoria cuando estoy importando 100K objetos de XML (no uso DM para las importaciones masivas) y solo mezclo las funciones de base de datos más complejas cuando las necesito

+0

interesante, no había pensado en eso. – cloudhead

0

Esta es realmente la cuestión de elegir Herencia vs Composición.

Personalmente prefiero la composición ya que parece ser una forma más natural de construir clases y objetos.

La composición le brinda más control sobre los comportamientos que desea incluir en su clase. En cuanto a la herencia, obtienes todo o nada. La composición le permite elegir los comportamientos que desea.

+1

Mixins no tienen nada que ver con la composición. Al igual que la herencia, un Mixin es una proposición de todo o nada. Y a diferencia de la composición, no puede cambiar el objeto que se mezcla en tiempo de ejecución. – KaptajnKold

4

El patrón DataMapper está destinado a proporcionar una capa que permite que el modelo de objetos de dominio diverja del esquema. ActiveRecord unifica el modelo de objetos y la estructura de la base de datos relacional.

por Martin Fowler:

objetos y bases de datos relacionales tienen diferentes mecanismos de estructuración de los datos. Muchas partes de un objeto, como las colecciones y la herencia, no están presentes en las bases de datos relacionales. Cuando construyes un modelo de objetos con mucha lógica de negocios, es valioso usar estos mecanismos para organizar mejor los datos y el comportamiento que los acompaña. Hacerlo conduce a esquemas variantes; es decir, el esquema del objeto y el esquema relacional no coinciden.

Aún necesita transferir datos entre los dos esquemas, y esta transferencia de datos se convierte en una complejidad en sí misma. Si los objetos en memoria conocen la estructura de la base de datos relacional, los cambios en uno tienden a ondear en el otro.

Data Mapper es una capa de software que separa los objetos en memoria de la base de datos. Su responsabilidad es transferir datos entre los dos y también aislarlos entre sí. Con Data Mapper, los objetos en memoria no necesitan saber siquiera que hay una base de datos presente; no necesitan código de interfaz SQL, y ciertamente no tienen conocimiento del esquema de la base de datos. (El esquema de la base de datos siempre ignora los objetos que lo utilizan). Dado que se trata de una forma de Mapper (473), el propio Data Mapper es desconocido para la capa de dominio.

0

ActiveRecord no debería realmente usar herencia, sino más bien incluir un módulo para agregar el comportamiento (principalmente la persistencia) a un modelo/clase. ¡ActiveRecord simplemente está usando el paradigma equivocado!

Por la misma razón, me gusta mucho MongoId sobre MongoMapper, porque deja al desarrollador la oportunidad de usar la herencia como una forma de modelar algo significativo en el dominio del problema.

Es triste que prácticamente nadie en la comunidad de Rails esté usando la "herencia de Ruby" de la forma en que se supone que debe usarse: para definir las jerarquías de clases, no solo para agregar comportamientos.