2009-11-02 9 views
12

Estoy buscando un ejemplo simple para ilustrar los beneficios de usar un modelo de dominio enriquecido. Idealmente, me gustaría un listado de código antes y después (que debe ser lo más breve posible).¿Hay un ejemplo de modelo de dominio enriquecido?

La lista del código anterior debe mostrar el problema que se resuelve usando un modelo de dominio anémico, y una gran cantidad de código de capa de servicio procedural, y la lista de código posterior debe mostrar el mismo problema utilizando un rico orientado a objetos modelo de dominio.

Idealmente, la lista del código debería estar en Java o Groovy, pero cualquier cosa bastante similar (por ejemplo, C#) sería suficiente.

+2

Por desgracia, es muy difícil de describir los beneficios de una respuesta corta. Si está escribiendo un sistema que contiene mucho comportamiento, en lugar de simplemente insertar/actualizar/eliminar, entonces puede beneficiarse al encapsular la lógica en un conjunto de clases (sus modelos de dominio). Es probable que no vea los beneficios hasta que tenga una solución lo suficientemente grande y su lógica de dominio sea lo suficientemente compleja. En ese caso, es muy agradable tener su lógica de dominio encapsulada en un solo lugar. –

Respuesta

-5

Esto no responde exactamente a su pregunta, pero veo lo opuesto al diseño impulsado por el dominio como el diseño basado en bases de datos. En el diseño basado en bases de datos, primero se crea el esquema de la base de datos y luego se crean las clases con pleno conocimiento de cómo se ve el esquema. La ventaja es que tiene una mejor comprensión de lo que está sucediendo bajo el capó y minimiza los efectos del desajuste de la impedancia. Sin embargo, la desventaja es que el esquema de la base de datos, debido a que es relacional en lugar de orientado a objetos, no se traduce a los objetos (por ejemplo, no existe el concepto de una colección en las bases de datos relacionales).

En el diseño impulsado por dominio, en teoría crea sus objetos de datos como lo haría con cualquier otra clase, y trata la base de datos simplemente como una capa de persistencia. En términos de Layman, la base de datos es solo un contenedor de almacenamiento y no le importa cómo se almacenan los objetos, solo que están almacenados de alguna manera. Esto elimina la falta de coincidencia de impedancia y tiene una cosa menos de qué preocuparse. En la práctica, sin embargo, aún debe tener en cuenta cómo se almacenan los objetos, y puede haber problemas de rendimiento cuando el ORM que está utilizando trata de escupir una consulta SQL compleja.

Editar:

He aquí un ejemplo de lo Dominio impulsada por el diseño debe ser, en principio. Digamos que usted tiene una clase de persona, al igual que (en C#):

public class Person 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public Address Address { get; set; } 
    public ICollection<Person> Relatives { get; set; } 
    public Company Employer { get; set; } 
} 

Ahora, en una base de datos relacional, esto probablemente va a traducir en 3 mesas, una mesa de persona, la tabla de direcciones, y la mesa de la empresa, con una montón de relaciones entre ellos. Sin embargo, esto es muy diferente de cómo el programador ve este objeto. El programador lo ve como una instancia de un objeto Persona con 4 parámetros, uno de los cuales es un ICollection. Esto no concuerda muy bien con la estructura de la tabla de la base de datos, por lo tanto, el "desajuste de impedancia", o en términos de Laymen, una diferencia en el diseño entre el modelo relacional y el modelo de objeto.

En el diseño de dominio impulsada, yo debería ser capaz de hacer esto:

Person person = new Person(); 
// set each property to something 
Database.Save(person); 

Ahora, el objeto persona es salva. Puedo recuperarlo, así:

Person databasePerson = Database.Get<Person>(idOfPerson); 

y va a devolver mi objeto Person, al igual que cómo era antes de lo guardé. De esta manera, no estoy preocupado en absoluto por cómo lo está guardando la base de datos, o me preocupo por la falta de correspondencia de la impedancia. Simplemente lo guardo y lo recupero según sea necesario.

Esto es todo en teoría sin embargo. En la práctica, probablemente tendrá que especificar manualmente la 'asignación', o cómo las clases saben de qué tabla/columna se obtienen datos en la base de datos. Puede ser bastante complejo cuando tratas de mapear a tipos más complejos como diccionarios y otros ADT, y también cuando tratas de extraer datos de múltiples tablas en una sola clase.

+4

No creo que este sea un ejemplo de un modelo de dominio enriquecido, porque el dominio que describes no contiene ningún comportamiento. – JasonTrue

+1

Este no es un dominio rico. En un dominio rico, probablemente no tengas setters, o solo unos pocos. – Martin

+0

Está hablando de mapeo relacional de objetos, que es un concepto totalmente diferente. Su clase Person contiene una estructura de datos, nada más. Necesita métodos y encapsulación (ocultación de datos e implementación) para transformarlo en un objeto real. – inf3rno

2

Creo que nadie ha hecho ese tipo de comparación y si lo hubiera sido, entonces no sería pequeño. Domain Driven Design intenta resolver la complejidad y un ejemplo simple no contiene complejidad.

Tal vez Domain Driven design Step by Step le dará algunas respuestas.

+0

enlace está obsoleto .. – xenoterracide

3

te voy a dar un ejemplo sencillo de auténtico código de producción:

Person.groovy:

List addToGroup(Group group) { 
    Membership.link(this, group) 
    return groups() 
    } 

Membership.groovy:

static Membership link(person, group) { 
    def m = Membership.findByPersonAndGroup(person, group) 
    if (!m) { 
     m = new Membership() 
     person?.addToMemberships(m) 
     group?.addToMemberships(m) 
     m.save() 
    } 
    return m 
} 

Siempre que quiero para unir a una persona a un grupo, solo puedo hacer person.addToGroup (grupo)

El código de procedimiento sería algo como esto, en el controlador:

def m = Membership.findByPersonAndGroup(person, group) 
if (!m) { 
     m = new Membership() 
     person?.addToMemberships(m) 
     group?.addToMemberships(m) 
     m.save() 
} 

A primera vista, se puede decir que se puede envolver en que una función y que son buenos para ir. Pero la ventaja del diseño de dominio enriquecido en mi humilde opinión es que está más cerca de la forma en que usted piensa, por lo tanto, está más cerca de racionalizar. En este ejemplo particular, solo quiero agregar una persona a un grupo, y el código solo leerá eso.

Este es un ejemplo breve como el que me pidió, pero es fácil expandir este ejemplo y ver que puede generar interacciones complejas con el modelado de dominio adecuado.

También puede ver Martin Fowler's Transaction Script vs Domain Model para una breve explicación de estos dos patrones, que considero relacionados con DDD.

Cuestiones relacionadas