2011-10-16 9 views
14

Mi equipo se esfuerza mucho por seguir el diseño impulsado por el dominio como una estrategia arquitectónica. Pero, la mayoría de las veces, nuestras entidades de dominio son bastante enimic. Nos gustaría poner más comportamiento empresarial/de dominio en nuestras entidades de dominio.DDD: ¿Qué tipo de comportamiento debo poner en una entidad de dominio?

Por ejemplo, Active Record pone acceso a datos en la entidad. No queremos eso porque estamos contentos de usar el patrón de repositorio para el acceso a los datos.

Además, diseñamos nuestro software para que sea SOLIDO (los cinco principios de diseño de software que Uncle Bob reunió). Entonces, es importante para nosotros que prestemos atención a la responsabilidad única, open-closed, liskov, segregación de interfaz e inversión de dependencia al diseñar nuestras entidades.

Entonces, ¿qué tipo de comportamiento deberíamos incluir? ¿De qué tipo deberíamos estar lejos?

+0

La única responsabilidad es bastante antitética al diseño impulsado por el dominio. Tuvimos una discusión interesante sobre esto en la reunión de NYCDDD hace un par de meses ... – Domenic

+0

Me interesaría esa discusión. No creo que sea el caso –

Respuesta

19

Ha pasado casi un año desde que hice esta pregunta y mi equipo y yo hemos aprendido mucho desde entonces. Así es como respondería esta pregunta hoy:

El dominio debe representar (en código) lo que es o hace la empresa (en la vida real). Las entidades de dominio, entonces, son los artefactos o actores que se encuentran en ese negocio de la vida real. ¿Qué tipo de comportamiento tienen esos artefactos y actores de la vida real? Todo ello. A su vez, ¿qué tipo de comportamiento DEBERÍAN tener las entidades de dominio sobre ellos? Todo ello.

Por ejemplo, en la vida real, un gerente puede contratar a un nuevo empleado. La representación del dominio de eso debe incluir entidades como "gerente" y "nuevo empleado". El gerente es el actor, aquí.

//newEmployee comes from somewhere else... possibly the UI 
//someManagerId comes from the logged in user 
var manager = _repository.Get<Manager>(someManagerId); 
manager.Hire(newEmployee); 

Por lo tanto, la entidad gestora modela/refleja el comportamiento del negocio real, aquí. La alternativa es saltarse la entidad gestora como actor, y empujarlo a la esquina por lo que un trabajo pesado "servicio de dominio" puede hacer todo el trabajo ... como esto:

//newEmployeeService comes from somewhere else... possibly injected using IOC 
newEmployeeService.Create(newEmployee, someManagerId); 

En un dominio anémica , usaría un servicio de dominio como este para crear o contratar un empleado. Funciona, pero no es expresivo y el comportamiento no es tan reconocible. ¿Quien hace que? ¿Por qué se le exige al gerente que cree un nuevo empleado?


Creo que cuando hice la pregunta originalmente, quería probar a empezar a incluir más el comportamiento de mis entidades, pero realmente no sabía cómo sin inyectar en mis servicios de entidades (por ejemplo, la inyección de constructor) Desde entonces, hemos aprendido algunos trucos nuevos y las entidades de nuestro equipo son súper expresivas. Aquí, en pocas palabras, lo que estamos haciendo:

  1. Intentamos, siempre que sea posible, usar entidades de actor para expresar la persona o cosa que está realizando la acción.
  2. Los actores tienen métodos que expresan las acciones que pueden realizar
  3. Cuando se necesita un servicio, se inyecta como argumento en el método donde se usa.
  4. Disparemos eventos de dominio usando BlingBag en cada método en cada entidad de dominio para proporcionar extensibilidad y dar a las entidades la capacidad de auto persistir.
+2

¿Qué pasa con el nuevoEmpleado? ¿Es creado por una fábrica o por el repositorio? ¿Levantará un evento de dominio por creación? ¿Los repositorios deberían manejar los eventos de dominio o deberían salir de la capa de dominio? Podría pedir demasiado: D – inf3rno

+0

También trato de hacer lo mismo. Como call = marketer.call (cliente); inquiry = marketer.makeInquiry (cliente, fecha); soy curioso cómo configuró su Manager en ORM y el diseño de la base de datos. ¿El gerente está en una herencia de tabla única? Estoy haciendo una herencia de tabla única, pero no necesito la columna discriminatoria. básicamente los actores tienen los mismos datos con diferentes roles solamente. –

+0

+1 para su punto n. ° 3 (Cuando se necesita un servicio, se inyecta como argumento en el método donde se usa). He visto esta sutileza eludir a muchas personas (incluyéndome a mí).Cuando lo piense, tiene sentido organizarlo de esta manera en lugar de usar la inyección de constructor, ya que deja en claro cuáles son las dependencias de cada acción. – MetaFight

0

comportamiento que trato de poner en mi dominio, entidades u objetos de valor.

validación antes de la persistencia. validación antes de la transición a un nuevo estado. Por ejemplo, la entidad raíz agregada de orden puede validar su estado interno y sus hijos agregados antes de pasar al estado Enviados. minimiza las propiedades de establecer y usa objetos de valor tanto como puedas. Primero, hace que el modelo sea más rico con el comportamiento. las entidades se vuelven más descriptivas en segundo lugar, rara vez pone su entidad en un estado inválido si debe usar métodos de objetos de valor como el método ApplyAdress en una entidad de persona que toma un objeto de valor de dirección como parámetro.

qué más ... Información de inteligencia. use su entidad y sus objetos de valor para controlar y restringir la información agregada. al igual que la identidad de persona puede ser un objeto de valor que maneja la uniqeuness de una persona. incapsulate ssn, ssn algoritm, maneja la suma de verificación de género en ssn etc.

+0

envíeme un correo electrónico si quisiera intercambiar discusiones más profundas sobre ddd y el comportamiento. –

0

El comportamiento que está en sus entidades debe reflejar el modelo de negocio. Lo que se puede hacer para o por esa entidad es que el mundo de los negocios debe ser algo que se pueda hacer a la clase de la entidad o por ella. Por ejemplo:

En un sistema de compras en línea, puede agregar un producto a su carrito. Por lo tanto, la clase Cart debería tener el siguiente aspecto:

public class Cart 
{ 
    //... 

    public void AddProduct(Product product) 
    { 
     ...code to add product to cart. 
    } 
} 

Se podría argumentar que los methids deben reflejar los casos de uso.

+0

o es Product # AddToCart (Cart) ??? – pinkpanther

3

Si tiene que preguntar qué comportamiento debe poner en la entidad de dominio, entonces probablemente no necesite DDD. Estoy tratando de ser útil aquí, porque he tenido mucho dolor tratando de adaptar DDD a un lugar al que no pertenecía.

DDD o incluso domain model son patrones que se pueden seguir después se descubre que el dominio de la complejidad es demasiado alto para cualquier otro patrón para trabajar. Entonces, solo CRUD no es adecuado para DDD. Desde mi punto de vista, DDD se ajusta cuando tiene un contexto delimitado que contiene complejo reglas de negocio que deben ejecutarse antes del estado de transición para la raíz agregada. Entonces no incluiría la validación en la definición de complejo.

El tipo de comportamiento que desea poner en sus entidades está íntimamente relacionado con el problema comercial que está tratando de resolver. La preocupación sobre la persistencia (repositorio, etc.) debe venir después (de hecho, la persistencia puede estar en un flujo de trabajo o tienda de eventos).

Espero que esto ayude.

Cuestiones relacionadas