2009-08-26 33 views
9

Digamos que tengo el típico entidad cocheDDD: subclases y entidades raíz

class Car : Entity 
{ 
    public double MaxSpeed { get; set; } 
    public Color Color { get; set; } 
    /* ... */ 
} 

Esta entidad, en mi modelo de dominio, sería la entidad raíz de un agregado.

Ahora digamos que estoy especializado en autos. Creo un Ferrari, y los felices propietarios de Ferraris gusta llamarlos por un apodo:

class Ferrari : Car 
{ 
    public string Nickname { get; set; } 
} 

Digamos que tengo otra entidad, el Compañía entidad. Sería la entidad de raíz de otra Agregado. Hay muchas personas trabajando en una empresa, representada por la entidad Persona. Las personas pueden tener autos. Pero el Presidente de una empresa suele ser muy rica y esta clase de personas, que tienen Ferraris:

class President : Person 
{ 
    public Ferrari Ferrari { get; set; } 
} 

En esta situación, tengo la entidad Presidente, que es dentro la Empresa Aggregate, que contiene una referencia a un Ferrari, una especialización de la entidad raíz de otro agregado.

¿Es esto correcto a la vista de DDD? ¿Puedo/debería considerar la especialización de las entidades raíz como entidades raíz del mismo agregado? Quiero decir, en el dominio que describí, ¿la entidad Ferrari también es la entidad raíz del Car Aggregate (ya que Ferrari también es un Auto)?


Ahora vamos a decir que tengo que persisten este modelo a una base de datos. Creo que mi pregunta no depende del marco OR/M que usaré.

¿Cómo debo compilar la tabla que contiene Cars? ¿Debo construir una sola tabla Cars, con una columna "CarType" (valores posibles: "Car", "Ferrari") y una columna Nullname Nickname?

¿O debería construir una tabla para Cars y una tabla para Ferraris, esta última teniendo su PK a FK de Cars?

Gracias!

Respuesta

2

Creo que comienza a perder gran parte de la flexibilidad del sistema al crear tipos concretos de estas entidades. El tipo de relación que está implicando es algo que generalmente entrego con una entidad "Tipo". Por ejemplo, tienes un auto. Un Ferrari es un tipo de automóvil. Las dos entidades que se derivan de eso son un Car y un CarType.

La forma en que está hablando de hacerlo, tendría que agregar nuevas entidades cada vez que se introduce un nuevo tipo. Si todo lo que intentas capturar es el "apodo" del automóvil, creo que es solo otro dato, y no otra entidad. A menos que tenga datos diferentes (es decirdiferentes nombres de propiedad) y/o diferencias de comportamiento en las entidades de Car para diferentes tipos, no gana mucho con este enfoque. Preferiría tener métodos de repositorio como FindCarByType() y tratar con un tipo de entidad para reducir el riesgo.

No soy de ninguna manera un experto en DDD, y estoy luchando con algunos conceptos (o más bien luchando con las múltiples interpretaciones de algunos conceptos). Estoy descubriendo que no hay una implementación 100% pura, y que hay matices en cada implementación que he visto.

Editar Sigue

veo que leí mal parte de lo que había escrito. Veo que ese apodo no es para todos los vehículos, sino solo para Ferrari: Coche. Creo que la respuesta es realmente "depende". ¿Cuánta especialización de dominio tiene en el resto de su modelo? Tener un apodo podría ser frecuente entre las entidades de Ferrari, pero ¿es exclusivo? No se trata solo de los datos reales, sino de los requisitos. Básicamente se trata de cuánta especialización esperas en estas entidades.

+0

¡Fantástico! ¡Gracias! En realidad, en mi sistema "real", los "Automóviles" son muy importantes, pero el "Ferrari" es la cosa más importante en mi dominio, de la que no puedo perder la pista, debo hacer estadísticas al respecto. –

4

No debe usar la herencia para modelar su dominio porque pronto tendrá problemas una vez que el modelo comience a ser complejo.

El presidente es simplemente un papel de la persona y la persona puede tener múltiples funciones. Tal vez el presidente obtuvo solo un papel, pero eso es simplemente accidental al elegir el ejemplo equivocado.

Ferrari tampoco debe heredarse del automóvil. No es obvio en el ejemplo de Ferrari, porque solo hacen un tipo de automóviles, pero consideran que la empresa fabrica muchos tipos, como camionetas, sedanes, hatchbacks, camiones, etc. Es probable que desee hacer clases para cada tipo que heredará de la clase de automóvil. Y entonces, ¿qué ... vas a hacer cinco clases de Toyota que heredarán de cada tipo? Tales como ...

Car -> Sedan -> ToyotaSedan 
Car -> Truck -> ToyotaTruck 
Car -> Hatchback -> ToyotaHatchback 

Eso sería ridículo.

Descargo de responsabilidad: No sé nada sobre automóviles. Sin embargo ...

No utilice la herencia para modelar su dominio. Nunca.

Pruébalo sin herencia y también será obvio cómo persistir en tu dominio.

+0

Gracias, lubos.Pero en este caso, en mi dominio "real", tengo * "autos", y hay autos "genéricos" y 2 tipos especiales de automóviles, "Ferrari" y "Porsche" que deben rastrearse, aunque son esencialmente "Cars". –

+3

todavía, evite la herencia. incluso si no lo hace, tendrá que hacerlo en uno o dos años porque su modelo probablemente se volverá más complicado en el futuro para capturar nuevos requisitos y la herencia causará mucho dolor en su diseño. los ejemplos de libros de texto para explicar la herencia como Cat y Dog son ambos Animals y Circle and Square son formas que dan una impresión equivocada de lo que realmente es la herencia y los programadores a menudo abusan de este concepto poderoso para modelar dominios. lea más aquí: http://www.geocities.com/tablizer/oopbad.htm#overeng (no soy el autor) –

+0

¡Muy buen artículo! ¡Gracias! –

3

Generalmente, cuando cruza límites de agregado raíz, solo permite que la referencia sea del ID del otro agregado raíz. Luego usa esa ID para buscar el otro agregado en su repositorio.

Por lo tanto, en su caso, usted desearía que el Presidente tuviera un Car ID y si alguna vez necesitara hacer algo en el automóvil del Presidente, usaría el Car ID para ir al depósito a buscar el automóvil. El presidente no tendría una referencia al auto en sí.

Ahora sobre eso Ferrari. Es un poco difícil hacer cumplir eso en la terminología DDD estándar. Normalmente pondrías alguna validación sobre la asignación de un automóvil a un presidente. O tal vez haya un CarBuyingService solo para presidentes que se asegure de hacerlo bien. Normalmente, las especializaciones DDD no son agregados raíz.

+0

Usted es el único que realmente respondió la pregunta –