DDD - acceder a repositorios desde entidades

59 views
Skip to first unread message

Jorge Rowies

unread,
Jul 4, 2010, 11:56:59 AM7/4/10
to AltNet-Hispano
Hola a todos

Tengo una inquietud y me gustaría saber la opinión de ustedes al
respecto.

En la VAN sobre DDD (http://altnet-hispano.pbworks.com/van-2009-12-19-
domain-driven-design) realizada por Angel "Java" Lopez, surgió (a los
1:28:25) brevemente un tema interesante sobre si es aconsejable que
una Entity pueda acceder directamente a un Repository. Fabio Maulo no
estaba muy de acuerdo sobre esto, mientras que Angel proponia un
ejemplo como el de un sistema para administración de consorcios
(edificios de departamentos) donde podía ocurrir que la entidad
Consorcio tenga ciertas responsabilidades y para que las mismas puedan
ser llevadas a cabo necesitaría acceder a repositorios de otras
entidades.

Este tema de acceder a repositorios desde entidades es algo que no me
termina de cerrar, Fabio comentaba que, a su entender, el acceso a
repositorios se deberia realizar desde un application service o un
domain service, pero no desde la entity.

En este post del grupo de DDD en yahoo (http://tech.groups.yahoo.com/
group/domaindrivendesign/message/2305?threaded=1), Evans da su opinión
al respecto, e inclusive (si no entendí mal) el propone que los
repositorios no se accedan desde ningún objeto del modelo (lo cual
incluye las entities y también los domain services).

Bueno, en definitiva, me gustaría saber que opinion tienen ustedes
sobre esto.

Desde ya, muchas gracias!

Raul Lopez

unread,
Jul 5, 2010, 3:22:14 PM7/5/10
to altnet-...@googlegroups.com
Inyectar el repository o el resutado de la invocacion al repository en
la entidad, en principio me parece que no hace mucha diferencia.
En alguna oportunidad cuando inyecte repositorios en entidades, al
refactorizar termine moviendo el acceso a repositorios a los servicios,
pero creo que el tema mas que nada pasa por determinar que tan _gordas_
queres que sean tus entidades en terminos de responsabilidades.
Solo una opinion...

Saludos,
Raul


Jorge Rowies escribi�:
> Hola a todos
>
> Tengo una inquietud y me gustar�a saber la opini�n de ustedes al


> respecto.
>
> En la VAN sobre DDD (http://altnet-hispano.pbworks.com/van-2009-12-19-

> domain-driven-design) realizada por Angel "Java" Lopez, surgi� (a los


> 1:28:25) brevemente un tema interesante sobre si es aconsejable que
> una Entity pueda acceder directamente a un Repository. Fabio Maulo no
> estaba muy de acuerdo sobre esto, mientras que Angel proponia un

> ejemplo como el de un sistema para administraci�n de consorcios
> (edificios de departamentos) donde pod�a ocurrir que la entidad


> Consorcio tenga ciertas responsabilidades y para que las mismas puedan

> ser llevadas a cabo necesitar�a acceder a repositorios de otras


> entidades.
>
> Este tema de acceder a repositorios desde entidades es algo que no me
> termina de cerrar, Fabio comentaba que, a su entender, el acceso a
> repositorios se deberia realizar desde un application service o un
> domain service, pero no desde la entity.
>
> En este post del grupo de DDD en yahoo (http://tech.groups.yahoo.com/

> group/domaindrivendesign/message/2305?threaded=1), Evans da su opini�n
> al respecto, e inclusive (si no entend� mal) el propone que los
> repositorios no se accedan desde ning�n objeto del modelo (lo cual
> incluye las entities y tambi�n los domain services).
>
> Bueno, en definitiva, me gustar�a saber que opinion tienen ustedes

José F. Romaniello

unread,
Jul 5, 2010, 3:44:32 PM7/5/10
to altnet-...@googlegroups.com
sobre la implementación: 
http://fabiomaulo.blogspot.com/2008/11/entities-behavior-injection.html

Si es bueno, malo, lindo, feo, práctico o complicado queda a criterio del televidente :)
Realmente yo no lo he necesitado hasta ahora... tuve en algún momento una intención de usarlo.


El 5 de julio de 2010 16:22, Raul Lopez <rlope...@gmail.com> escribió:
Inyectar el repository o el resutado de la invocacion al repository en la entidad, en principio me parece que no hace mucha diferencia.
En alguna oportunidad cuando inyecte repositorios en entidades, al refactorizar termine moviendo el acceso a repositorios a los servicios,
pero creo que el tema mas que nada pasa por determinar que tan _gordas_ queres que sean tus entidades en terminos de responsabilidades.
Solo una opinion...

Saludos,
Raul


Jorge Rowies escribió:

Hola a todos

Tengo una inquietud y me gustaría saber la opinión de ustedes al
domain-driven-design) realizada por Angel "Java" Lopez, surgió (a los

1:28:25) brevemente un tema interesante sobre si es aconsejable que
una Entity pueda acceder directamente a un Repository. Fabio Maulo no
estaba muy de acuerdo sobre esto, mientras que Angel proponia un
ejemplo como el de un sistema para administración de consorcios
(edificios de departamentos) donde podía ocurrir que la entidad

Consorcio tenga ciertas responsabilidades y para que las mismas puedan
ser llevadas a cabo necesitaría acceder a repositorios de otras

entidades.

Este tema de acceder a repositorios desde entidades es algo que no me
termina de cerrar, Fabio comentaba que, a su entender, el acceso a
repositorios se deberia realizar desde un application service o un
domain service, pero no desde la entity.

En este post del grupo de DDD en yahoo (http://tech.groups.yahoo.com/
group/domaindrivendesign/message/2305?threaded=1), Evans da su opinión
al respecto, e inclusive (si no entendí mal) el propone que los
repositorios no se accedan desde ningún objeto del modelo (lo cual
incluye las entities y también los domain services).

Bueno, en definitiva, me gustaría saber que opinion tienen ustedes

sobre esto.

Desde ya, muchas gracias!

 

--
Has recibido este mensaje porque estás suscrito al grupo "AltNet-Hispano" de Grupos de Google.
Para publicar una entrada en este grupo, envía un correo electrónico a altnet-...@googlegroups.com.
Para anular tu suscripción a este grupo, envía un correo electrónico a altnet-hispan...@googlegroups.com
Para tener acceso a más opciones, visita el grupo en http://groups.google.com/group/altnet-hispano?hl=es.


Carlos Peix

unread,
Jul 6, 2010, 8:40:30 AM7/6/10
to altnet-hispano
Hola Jorge,

Yo me he encontrado en la necesidad de inyectar servicios de infraestructura (repositorios, notificacion, etc.) en entidades, en general pasandolos como parametro de algun metodo (como una manera de reducir al minimo el scope de la dependencia).

En general lo veo como algo no deseable aunque muchas veces no he tenido tiempo o lucidez para evitarlo.

Cuando he podido evitarlo ha sido repensandolo y casi siempre termine viendo que el nuevo diseño, ademas de evitar la inyeccion de la dependencia, terminaba mejor alineado con nuestros amigos los principios SOLID, GRASP y OOD en general.

Un abrazo

----------------------------------
Carlos Peix

2010/7/4 Jorge Rowies <jorge....@gmail.com>

Ariel Piñeiro

unread,
Jul 6, 2010, 9:42:30 AM7/6/10
to altnet-...@googlegroups.com
Muchachos tengo que participar en una arquitectura nueva. Alguien conoce el concepto de CQRS (Command-Query Responsibility Segregation) o que me pueda orientar con algún paper en español?

2010/7/6 Carlos Peix <carlo...@gmail.com>

Carlos Peix

unread,
Jul 6, 2010, 9:50:44 AM7/6/10
to altnet-...@googlegroups.com
Hola Ariel,

Podrias empezar un nuevo thread? (desde cero, no respondiendo a este mensaje cambiando el asunto)

Creo que es un tema que se lo merece y seguramente tendras muchos aportes.

Gracias

----------------------------------
Carlos Peix
Moderador

2010/7/6 Ariel Piñeiro <arie...@gmail.com>

Jorge Rowies

unread,
Jul 6, 2010, 10:08:47 AM7/6/10
to altnet-...@googlegroups.com
Antes que nada, gracias a todos por las opiniones! es tranquilizante ver que a otros les ha pasado lo mismo que a uno ;)

Comparto con Carlos que en ocasiones esta necesidad de utilizar repositorios desde entidades se soluciona repensando el diseño, en particular me ha pasado varias veces que a primera vista era necesario utilizar un repository desde una entity y finalmente repensando el diseño esto no resultó necesario. El problema que se me plantea es cuando uno mira el diseño y ve que todo está bien, y justamente modificarlo para que no sea necesario utilizar un repositorio es forzar el diseño para que represente algo que no debería representar.

Ultimamente me está gustando cada vez mas la idea de utilizar repositorios desde la capa del dominio, pero no desde entidades, sinó desde servicios de dominio. El razonamiento que me lleva a esto es que si una entidad A necesita un repositorio para acceder a otra entidad B, es porque no es posible acceder a esa entidad B via las relaciones que tiene la entidad A. Con lo cual es probable que lo que necesite hacer (realizar alguna validación o alguna otra acción) no deba ser responsabilidad de la entidad A, sinó de algún servicio de dominio. (Digo servicio de dominio y no servicio de aplicación, porque me interesa que esta lógica quede plasmada dentro de mi modelo de dominio y no fuera de él)

Tiene sentido este razonamiento?

saludos,
Jorge

2010/7/6 Carlos Peix <carlo...@gmail.com>

Nelo Pauselli

unread,
Jul 6, 2010, 12:24:16 PM7/6/10
to altnet-...@googlegroups.com
Hola Jorge,

yo también vengo incursionando en este tema y, al igual que a vos, no
me termina de agradar el tema de los repositorios en las entidades.
Quizás, el tema es que aun pensamos en términos de entidades como una
subclase del dominio. Como ya han planteado alguna vez (creo que
Carlos), podemos pensar en:

objetos con estado solamente <-> objetos con estado y lógica <->
objetos con lógica solamente

donde en la izquierda tenemos lo que llamamos entidades, a la derecha
lo que llamamos servicios de negocio ¿y las del medio?, lo que está
claro es que todos son objetos del dominio.

Lo que me parece que se pierde con todo esto es la claridad que da la
estratificación de los sistemas, me suena a una bolsa muy grande,
donde solo se distingue entre el Dominio y lo externo, pero claro,
estamos hablando de DDD.

Retomando el concepto de entidades, coincido con que la entidad A
debería resolver lo que esté a su alcance, es decir lo que pueda hacer
conociendo sus propiedades, pero entonces pienso que una propiedad
podría ser el repositorio y vuelvo a empezar.

pregunta: ¿una Entidad podría invocar a un Servicio de Negocio?

A mi aun me gusta pensar en la división de componentes por sus
responsabilidades y pensar la complejidad del diseño desde las
relaciones entre componentes (o partes de estos), es decir sus
referencias, lo que sería un enfoque mas neuronal (la complejidad de
un sistema neuronal se determina por la cantidad y calidad de sinapsis
y no por la capacidad individual de cada neurona, que solita es
bastante limitada). Todo lo que pueda resolver una entidad desde su
capacidad que lo resuelva. ya si tienen que intervenir mas actores (y
que no se conocen) pienso que debería ser un servicio de negocio que
orquesta a los actores donde preferentemente trata de ejecutar
acciones de los actores y no de interrogarlos. Es decir, en el
servicio de negocio, en lugar de:

if (persona.Estado==Estados.EstadoA)
persona.Estado = EstadoB;

pondría:

persona.PonerEstadoB();

y las verificaciones que deba hacer, referentes a la incumbencia de
persona, que lo haga el objeto persona.


Bueno, ya me extendí demasiado para un mail.

Saludos.
Nelo.

2010/7/6 Jorge Rowies <jorge....@gmail.com>:

Nelo Pauselli

unread,
Jul 6, 2010, 12:44:19 PM7/6/10
to altnet-...@googlegroups.com
ah, y no olvidemos que DDD es una metodología que propone una
arquitectura y no solo una arquitectura.


2010/7/6 Nelo Pauselli <nelopa...@gmail.com>:

Lionel Orellana

unread,
Jul 6, 2010, 4:30:53 PM7/6/10
to AltNet-Hispano
Yo creo que la clave aqui es que los Repositorios en DDD deben dar la
ilusion de ser una coleccion in-memory. En ese sentido no son un DAO
tipico. Para el cliente del repositorio la base de datos no existe.
Por eso no tengo problemas con que las entidades usen repositorios de
otras entidades.

On Jul 7, 2:44 am, Nelo Pauselli <nelopause...@gmail.com> wrote:
> ah, y no olvidemos que DDD es una metodología que propone una
> arquitectura y no solo una arquitectura.
>
> 2010/7/6 Nelo Pauselli <nelopause...@gmail.com>:
> > 2010/7/6 Jorge Rowies <jorge.row...@gmail.com>:
> >> Antes que nada, gracias a todos por las opiniones! es tranquilizante ver que
> >> a otros les ha pasado lo mismo que a uno ;)
>
> >> Comparto con Carlos que en ocasiones esta necesidad de utilizar repositorios
> >> desde entidades se soluciona repensando el diseño, en particular me ha
> >> pasado varias veces que a primera vista era necesario utilizar un repository
> >> desde una entity y finalmente repensando el diseño esto no resultó
> >> necesario. El problema que se me plantea es cuando uno mira el diseño y ve
> >> que todo está bien, y justamente modificarlo para que no sea necesario
> >> utilizar un repositorio es forzar el diseño para que represente algo que no
> >> debería representar.
>
> >> Ultimamente me está gustando cada vez mas la idea de utilizar repositorios
> >> desde la capa del dominio, pero no desde entidades, sinó desde servicios de
> >> dominio. El razonamiento que me lleva a esto es que si una entidad A
> >> necesita un repositorio para acceder a otra entidad B, es porque no es
> >> posible acceder a esa entidad B via las relaciones que tiene la entidad A.
> >> Con lo cual es probable que lo que necesite hacer (realizar alguna
> >> validación o alguna otra acción) no deba ser responsabilidad de la entidad
> >> A, sinó de algún servicio de dominio. (Digo servicio de dominio y no
> >> servicio de aplicación, porque me interesa que esta lógica quede plasmada
> >> dentro de mi modelo de dominio y no fuera de él)
>
> >> Tiene sentido este razonamiento?
>
> >> saludos,
> >> Jorge
>
> >> 2010/7/6 Carlos Peix <carlos.p...@gmail.com>
>
> >>> Hola Jorge,
> >>> Yo me he encontrado en la necesidad de inyectar servicios de
> >>> infraestructura (repositorios, notificacion, etc.) en entidades, en general
> >>> pasandolos como parametro de algun metodo (como una manera de reducir al
> >>> minimo el scope de la dependencia).
> >>> En general lo veo como algo no deseable aunque muchas veces no he tenido
> >>> tiempo o lucidez para evitarlo.
> >>> Cuando he podido evitarlo ha sido repensandolo y casi siempre termine
> >>> viendo que el nuevo diseño, ademas de evitar la inyeccion de la dependencia,
> >>> terminaba mejor alineado con nuestros amigos los principios SOLID, GRASP y
> >>> OOD en general.
> >>> Un abrazo
> >>> ----------------------------------
> >>> Carlos Peix
>
> >>> 2010/7/4 Jorge Rowies <jorge.row...@gmail.com>

Gustavo Ringel

unread,
Jul 6, 2010, 4:35:09 PM7/6/10
to altnet-...@googlegroups.com
El problema no es si se accede a datos o no de otro repositorio, el problema es responsabilidades. En general una entidad que es el estado de un objeto, es dudoso que tenga que saber como afectar/obtener el estado de otro objeto. 

Gustavo.

2010/7/6 Lionel Orellana <lion...@gmail.com>

Jorge Rowies

unread,
Jul 6, 2010, 7:30:41 PM7/6/10
to altnet-...@googlegroups.com
Hola Nelo, como andas?

Por lo que estuve leyendo sobre DDD, no es recomendable que las entidades solo tengan estado y nada de comportamiento, esto se lo suele llamar anemic domain model, claro está que en cualquier modelo podemos encontrar este tipo de cosas, pero es algo a revisar, dependerá de lo que estemos modelando seguramente el hecho de que esto esté bien o mal.

Siguiendo DDD y lo que menciona Fowler sobre anemic domain model, lo que si estaria mal es tomar como REGLA que toda entidad solo debe tener estado y el comportamiento se deba delegar en clases que solo tengan lógica, estas clases terminarian siendo los servicios del dominio y según leí en el libro de Evans, un buen servicio de dominio debería tener estas tres características:

  1. The operation relates to a domain concept that is not a natural part of an ENTITY or VALUE OBJECT.

  2. The interface is defined in terms of other elements of the domain model.

  3. The operation is stateless.

Así que, según el punto 1, si la lógica que estamos poniendo en el servicio sería natural que esté en una entity o value object, deberíamos ponerla ahí y no en el servicio.

Coincido en que todo siempre apunta al tema de las responsabilidades de los objetos, lo cual es fundamental a la hora de tomar decisiones de diseño.

Un abrazo,
Jorge

2010/7/6 Nelo Pauselli <nelopa...@gmail.com>

Lionel Orellana

unread,
Jul 7, 2010, 4:49:55 PM7/7/10
to AltNet-Hispano
Eso seria como no tener asociaciones de ningun tipo. Las
responsabilidades pueden estar muy bien separadas y todavia tener
relaciones entre las entidades. No entiendo muy bien tu punto.

Lionel.

On Jul 7, 6:35 am, Gustavo Ringel <gustavo.rin...@gmail.com> wrote:
> El problema no es si se accede a datos o no de otro repositorio, el problema
> es responsabilidades. En general una entidad que es el estado de un objeto,
> es dudoso que tenga que saber como afectar/obtener el estado de otro
> objeto.
>
> Gustavo.
>
> 2010/7/6 Lionel Orellana <lione...@gmail.com>
> > > >>>> altnet-hispan...@googlegroups.com<altnet-hispano%2Bunsubscribe@go oglegroups.com>
> > > >>>> Para tener acceso a más opciones, visita el grupo en
> > > >>>>http://groups.google.com/group/altnet-hispano?hl=es.
>
> > > >>> --
> > > >>> Has recibido este mensaje porque estás suscrito al grupo
> > "AltNet-Hispano"
> > > >>> de Grupos de Google.
> > > >>> Para publicar una entrada en este grupo, envía un correo electrónico
> > a
> > > >>> altnet-...@googlegroups.com.
> > > >>> Para anular tu suscripción a este grupo, envía un correo electrónico
> > a
> > > >>> altnet-hispan...@googlegroups.com<altnet-hispano%2Bunsubscribe@go oglegroups.com>
> > > >>> Para tener acceso a más opciones, visita el grupo en
> > > >>>http://groups.google.com/group/altnet-hispano?hl=es.
>
> > > >> --
> > > >> Has recibido este mensaje porque estás suscrito al grupo
> > "AltNet-Hispano" de
> > > >> Grupos de Google.
> > > >> Para publicar una entrada en este grupo, envía un correo electrónico a
> > > >> altnet-...@googlegroups.com.
> > > >> Para anular tu suscripción a este grupo, envía un correo electrónico a
> > > >> altnet-hispan...@googlegroups.com<altnet-hispano%2Bunsubscribe@go oglegroups.com>
> > > >> Para tener acceso a más opciones, visita el grupo en
> > > >>http://groups.google.com/group/altnet-hispano?hl=es.
>
> > --
> > Has recibido este mensaje porque estás suscrito al grupo "AltNet-Hispano"
> > de Grupos de Google.
> > Para publicar una entrada en este grupo, envía un correo electrónico a
> > altnet-...@googlegroups.com.
> > Para anular tu suscripción a este grupo, envía un correo electrónico a
> > altnet-hispan...@googlegroups.com<altnet-hispano%2Bunsubscribe@go oglegroups.com>

Gustavo Ringel

unread,
Jul 7, 2010, 5:35:47 PM7/7/10
to altnet-...@googlegroups.com
No hay ningun punto porque la discusion aca es teorica.
Tampoco hay ningun punto en dercir que las relaciones tienen sus reponsabilidades y las entidades tener relaciones, es decir, entre eso, y la discusion de usar un Repositorio en una entidad no hay un contacto directo.

En general que una instancia de una entidad A, afecte a traves de un repositorio una entidad B, implica que cambios en el repositorio de B tienen efecto sobre A, la cual no tiene relacion con B (sino no le hubiera inyectado el Repositorio para hacer algo entre A y B, en general trato de ahorrarme eso.

Gustavo.

2010/7/7 Lionel Orellana <lion...@gmail.com>

Carlos Peix

unread,
Jul 7, 2010, 5:36:56 PM7/7/10
to altnet-hispano
Hola Lionel,

Yo creo que hay una diferencia en lo que planteo Gustavo y lo que vos interpretas (si les entiendo bien a ambos).

Si un objeto accede a otro (o a otros) mediante una referencia que almacena en una variable de instancia, estamos bien. En cambio, si un objeto debe recurrir a un repositorio para encontrar otro objeto por algun criterio determinado, entonces el primer objeto tiene una responsabilidad que no le corresponde.

Espero que esto clarifique

----------------------------------
Carlos Peix

2010/7/7 Lionel Orellana <lion...@gmail.com>

Jorge Rowies

unread,
Jul 7, 2010, 7:26:04 PM7/7/10
to altnet-...@googlegroups.com
Trataré de plantear un ejemplo concreto:

Tengo una clase Cliente, y ademas las clases Factura y OrdenCompra, las cuales tienen ambas una referencia a Cliente.

Si se plantea el caso de uso "Inhabilitación de cliente", el cual implica marcar al cliente con un flag que indica que está inhabilitado, pero además de eso debo hacer lo siguiente:

1) verificar que el cliente no tenga facturas impagas, en cuyo caso no lo puedo inhabilitar
2) si el cliente tiene ordenes de compra pendientes, debo cancelarlas

La pregunta que se me plantea es, pongo en mi clase Cliente dos properties con la lista de Facturas y de Ordenes de Compra del mismo?

Si hago eso, la entity Cliente va a saber como realizar 1) y 2)

Si no hago eso, necesito desde "algún lado" llamar a los repositories de Factura y OrdenCompra (GetFacturasPorCliente/GetOrdenesCompraPorCliente, o algo asi) para obtenerlas y realizar 1) y 2)

"algún lado" es la misma entity Cliente? o este caso de uso se debería llevar a cabo desde otro lado como puede ser un domain service o un application service, el cual debería colaborar con:
a) la entidad Cliente
b) los repositorios de Factura y OrdenCompra
c) las entidades Factura y OrdenCompra

?

Mi opinión personal es que esta lógica deberia pertenecer a mi capa de dominio ya que es fundamental en mi negocio, por lo tanto no lo pondría en un application service, pero...., ustedes lo pondrían en un domain service ó en la entidad Cliente? (y en este último caso, lo harían usando los repositorios o agregando las listas de Facturas y Ordenes relacionadas en la entidad de Cliente?)

Saludos!


2010/7/7 Carlos Peix <carlo...@gmail.com>

--
Has recibido este mensaje porque estás suscrito al grupo "AltNet-Hispano" de Grupos de Google.
Para publicar una entrada en este grupo, envía un correo electrónico a altnet-...@googlegroups.com.
Para anular tu suscripción a este grupo, envía un correo electrónico a altnet-hispan...@googlegroups.com

Cristian Prieto

unread,
Jul 7, 2010, 11:28:33 PM7/7/10
to altnet-...@googlegroups.com
Jorge,

Algo que repito e insisto cada vez que hablamos de DDD: Todo se basa en el modelado del dominio y el lenguaje ubicuo... Lo demás es el simple uso de los patrones expuestos en el libro de Evans... En otras palabras, si bien la mayoría de las veces no "haces" DDD si usas los patrones...

En el caso particular que expones con el caso de Cliente, Facturas y Órdenes de Compra necesito aclarar que para la mayoría de los dominios (ojo, un dominio depende del dueño del dominio, ya sea empresa, consultor, el chato que te explica el negocio... etc) luciría algo así:
  • Cliente, Factura y Órdenes son entidades
Y qué pasa cuando quieres desactivar a Cliente? recordemos que según lo que me dices un cliente al desactivarse NO debe tener facturas no pagadas y órdenes en tránsito... Si tu preocupación es la interacción entre los repositorios basta con entender la definición de repositorio de Evans (que difiere ligeramente de la que conocemos de Fowler):

"Un repositorio es una colección en memoria que contiene Root Aggregates"
[Ojo, como se daran cuenta estoy "parafraseando" a Evans.]

El secreto es simple, la palabra Root Aggregates, son simplemente entidades centrales que contienen otras entidades o Value Objects. Un repositorio jamás retornará Value Objects. Un repositorio puede, pero bajo casos especiales, retornar no Root Aggregates. 

En el caso en particular del Cliente, Factura y Órdenes, el cliente es tu root aggregate. También es importante que una entidad no debe ser anémica y por lo tanto debe contener comportamiento (a esto se le llama Domain Object), una forma de resolver tu problema es el siguiente:

  • Tu Cliente contiene una colección de Facturas y Órdenes de compra
  • Tu Cliente posee un método llamado "Inactivar"
  • No hay forma de inactivar un cliente a menos que se llame al método inactivar (en este caso vez que Cliente contiene comportamiento, no solamente datos)
  • El método "Inactivar" de Cliente busca si tiene Facturas no pagadas y Órdenes de compra que esten en curso, si es así tira una excepción de validación o la que te sea más descriptiva
  • La entidad Cliente no puede obtenerse de ninguna otra forma más que usando RepositorioCliente
Quizás mi ejemplo esta algo "escueto" pero estoy abierto a comentarios :)


Cristian Prieto


2010/7/7 Jorge Rowies <jorge....@gmail.com>

Edgar Ramos

unread,
Jul 7, 2010, 11:43:56 PM7/7/10
to altnet-...@googlegroups.com
De poco a poquito voy con DDD...

Siempre aprendo un poco e investigo el doble, gracias Cristian

Saludos

Edgar

Gustavo Ringel

unread,
Jul 8, 2010, 1:32:56 AM7/8/10
to altnet-...@googlegroups.com
Si eso esta mejor explicado que con mis entidades A y B no relacionadas en forma directa :)


2010/7/8 Carlos Peix <carlo...@gmail.com>

--
Has recibido este mensaje porque estás suscrito al grupo "AltNet-Hispano" de Grupos de Google.
Para publicar una entrada en este grupo, envía un correo electrónico a altnet-...@googlegroups.com.
Para anular tu suscripción a este grupo, envía un correo electrónico a altnet-hispan...@googlegroups.com

daniel...@gmail.com

unread,
Jul 8, 2010, 6:52:49 AM7/8/10
to altnet-...@googlegroups.com
En tu ejemplo lo primero que me pregunto es si no te falto modelar algo en el dominio...
De todas formas esto no responde a la pregunta central sobre quien y desde donde accede al repo...

Daniel Calvin

Enviado desde mi BlackBerry de Movistar (http://www.movistar.com.ar)


From: Jorge Rowies <jorge....@gmail.com>
Date: Wed, 7 Jul 2010 20:26:04 -0300
Subject: Re: [altnet-hispano] Re: DDD - acceder a repositorios desde entidades

daniel...@gmail.com

unread,
Jul 8, 2010, 7:05:45 AM7/8/10
to altnet-...@googlegroups.com
Hola Cristian

Me da la sensacion que las responabilidades de cliente se han sobrevaluado....
Si bien no hay modelos correctos o incorrectos, ya que en definitiva el modelo es una astraccion del dominio segun la visión del observador que construye ese modelo, lo que si sucede es que muchas veces el resultado del modelado es un poco perverso.
En este caso que el inhabiltarse sea responsabilidad del propio cliente no parece respetar EXPERTO en INFORMACION, el resultado es acoplamiento y una consecuencia es que se sigue agregando complejidad a la clase Cliente.
Tal vez la pregunta existe como consecuencia de esto.

Solo una mirada sobre el tema, tantas veces me olvide de modelar algo ... :))


Daniel Calvin

Enviado desde mi BlackBerry de Movistar (http://www.movistar.com.ar)


From: Cristian Prieto <keme...@gmail.com>
Date: Wed, 7 Jul 2010 21:28:33 -0600
Subject: Re: [altnet-hispano] Re: DDD - acceder a repositorios desde entidades

Nelo Pauselli

unread,
Jul 8, 2010, 8:10:09 AM7/8/10
to altnet-...@googlegroups.com
En el caso que planteas yo usaría un domain service.

en el problema que estás intentando modelar ¿el cliente real es quien
se inactiva? creo que no. El poner o no la colección de Facturas y
Ordenes de Compra en el cliente creo que debería ser una necesidad del
diseño y no de la implementación.

Pero si de todas formas querés ir con las Facturas y Ordenes de Compra
en el cliente, quizás podrías poner un TieneFacturas y
TieneOrdenesDeCompra (a los sumo un CantidadDe...) ya que lo que te
interesa es saber si tiene o no tiene. (pesando en la escalabilidad de
tu sistema).

Nelo.

2010/7/8 <daniel...@gmail.com>:

Jorge Rowies

unread,
Jul 8, 2010, 9:50:48 AM7/8/10
to altnet-...@googlegroups.com
Daniel, seguramente me faltó modelar algo ya que esto no es un caso real, es solo un ejemplo pensado rápidamente ;)



Jorge Rowies

unread,
Jul 8, 2010, 10:42:14 AM7/8/10
to altnet-...@googlegroups.com
Cristian, está claro que DDD no son los patrones, sinó que va mucho mas allá, pero yo no diría que lo demás es el "simple" uso de los patrones... hay complejidad en aplicarlos correctamente y, en gran parte, del hecho que los apliquemos correctamente dependerá que nuestro modelo sea escalable, mantenible, testeable, etc...

Tal como menciona Daniel, creo que todo depende de las responsabilidades que le querramos dar a nuestras entidades, y la única forma de determinar esto es estudiando el dominio.

Quizás mi error es tratar de responder un problema que depende del dominio con un ejemplo totalmente aislado de la información que provee el estudio de un dominio de negocio. Quizás para un dominio determinado está bien que Cliente tenga una lista de Facturas y Ordenes y quizás para otro dominio, esto traiga mas problemas que ventajas...

Saludos


2010/7/8 Cristian Prieto <keme...@gmail.com>

Cristian Prieto

unread,
Jul 8, 2010, 12:08:27 PM7/8/10
to altnet-...@googlegroups.com
En el caso particular donde Cliente sea tu Root Aggregate el repositorio puedes accederlo en dos lugares :
1. En un Domain Service, en dado caso la operación "Inactivar cliente" sea suficientemente compleja como para necesitar uno (en este caso no la siento compleja como para separarla)
2. En un Application Service, que como recordaran guarda la implementación o la lógica orientada al uso inmediato de cliente. De igual manera yo no tendría repositorios separados de Ordenes de compra o Facturas, ya que estas estarían aglutinadas a Cliente (su root aggregate).

Un caso particular podría ser que Cliente ahora posee responsabilidades adicionales, es totalmente normal, por eso es un "Domain Object" (recuerden, un Domain Object encapsula la "lógica del negocio" y son excelentes para casos donde la lógica suele cambiar con el tiempo), se me ocurren solamente un par de casos o lógica encapsulada en Cliente:

- Inactivar cliente (a quien inactivas? al cliente!)
- Agregar una nueva Orden de Compra (a quién se la agregas? al cliente!)
- Agregar una nueva Factura (a quién se la agregas? al cliente!)

Alguien podría preguntarme: AJA! pero el proceso de crear una factura es algo complejo, es ahí donde entran las Factories de dominio... Es interesante porque Factura y Orden de compra también deberían ser Domain Objects.

No sobrevaluo la experiencia del cliente, me es TOTALMENTE necesaria... nadie sabe más de su negocio que el, y si el lo maneja de esa manera no soy nadie para decirle como hacerlo... ¿Hay acoplamiento? no, para eso tenemos sobradas formas de evitarlo....


Saludos a todos, 

-- Cristian


Cristian Prieto

unread,
Jul 8, 2010, 12:21:06 PM7/8/10
to altnet-...@googlegroups.com
Yep, es por eso que en mi primer correo aclaré algo:

"En el caso particular que expones con el caso de Cliente, Facturas y Órdenes de Compra necesito aclarar que para la mayoría de los dominios (ojo, un dominio depende del dueño del dominio, ya sea empresa, consultor, el chato que te explica el negocio... etc) luciría algo así:"

De hecho debo confesarlo, armé la clase de cliente de esa forma para tratar de responder una pregunta específica y por la que creo que comenzó esta thread:

¿Deben mis entidades consumir o tener acceso al repositorio de otra entidad?

Bueno, creo que quedó claro que para mi en este caso específico: no directamente

La siguiente pregunta que quise ayudar a responder (pero quizás no lo logré... que se yo...)

Bien, y si tengo muchas entidades quien llama al repositorio de quien y como hago si el caso cliente necesita desactivarse....

Y bueno, fue ahí donde nació la idea de presentarles a nuestro amigo los Root Aggregates :)


Pero como diría nuestro amigo Fabio,

Qué se yo, salgo muy poco!!!



-- Cristian


2010/7/8 Jorge Rowies <jorge....@gmail.com>

Jorge Rowies

unread,
Jul 8, 2010, 2:00:29 PM7/8/10
to altnet-...@googlegroups.com
Totalmente de acuerdo Cristian, te agradezco mucho a vos y a todos los demás toda la información que han compartido, la verdad que es de muchisima ayuda.

Mil gracias!!

2010/7/8 Cristian Prieto <keme...@gmail.com>

Carlos Peix

unread,
Jul 9, 2010, 7:06:28 AM7/9/10
to altnet-hispano
Una aclaracion al concepto de Aggregates que muy bien presento Cristian.

Evans define los aggregates (con la foto del racimo de uvas en su libro) como un objeto o un conjunto de objetos "fuertemente" relacionados.

Todo aggregate tiene un objeto principal, un "referente" que es lo que Evans llama el "aggregate root" y propone algunas conductas relacionadas, como por ejemplo que los repositorios deberia devolver aggregate(s) referenciados por su "root", que no deben hacerse referencias desde objetos externos a otro objeto que no sea el root, que deben persistirse en forma completa, nunca por partes (mas alla de las optimizaciones que hagan los ORMs), etc.

Otro punto que me ha ayudado es pensar los aggregates en funcion de objetos (instancias) y no en funcion de clases o tipos.

Para poner un ejemplo trillado pero creo que util, en un modelo donde tenemos una factura con su cliente, la cual contiene sus items que, ademas de definir cantidad tienen una referencia a un producto, por ejemplo las clases: Factura, ItemFactura, Cliente y Producto.

En este caso tenemos tres aggregates: Factura, Cliente y Producto, siendo el aggregate Factura el que contiene objetos de mas de un tipo (una instancia de Factura seria el root, instancias de ItemFactura serian objetos internos).

Siento que debi aclarar esto porque no es lo mismo decir en ingles "root aggregate" que "aggregate root", con el primer nombre podria pensarse que hay un aggregate mas importante que otros y en mi opinion no es asi.

Un saludo

----------------------------------
Carlos Peix

2010/7/8 Jorge Rowies <jorge....@gmail.com>

Lionel Orellana

unread,
Jul 9, 2010, 7:23:49 AM7/9/10
to AltNet-Hispano


Disculpen mis comentarios tardios pero estoy unas 14 horas adelantado
(o atrasado?).

Si Cliente es el Aggregate Root y Factura y Orden son parte del mismo
Aggregate entonces nada mas tenemos un Repositorio para el Cliente.
Tanto la Factura como la Orden se acceden a traves del Cliente, como
bien ha dicho Cristian. En este caso cuando usamos el
RepositorioCliente para obtener un cliente particular este debe venir
inflado ya con sus Facturas y Ordenes (tal vez usando lazy-loading con
NHibernate).

Es posible pensar un dominio donde al menos Factura sea el root de su
propio Aggregate. Es en este caso cuando contamos con un
RepositorioFactura que podriamos utilizar desde el Cliente para inflar
la coleccion:

public IList<Factura> Facturas
{
get
{
repositorioDeFacturas.GetByClient(this);
}
}

En otra discusion del grupo de DDD en yahoo mencionaban esto (http://
tech.groups.yahoo.com/group/domaindrivendesign/message/2002).

Comparto la idea general de que es efectivamente responsabilidad de
Cliente devolver sus Facturas. El codigo que utiliza la clase Cliente
no tiene por que saber de donde salieron esas Facturas, simplemente se
las pide al Cliente.

La otra alternativa es eliminar la Asociaion del modelo. Segun Evans
las asociaciones complican la implementacion y es recomendable dejar
solo las que sean estrictamente necesarias. Al elimiar la asociaion
creo que pasaria a ser responsabilidad del Application Service el como
obtener las Facturas. InactivarCliente usaria el RepositorioFactura
para chequear si existe alguna sin pagar, el RepositorioCliente para
obtener el cliente e inactivarlo y el RepositorioOrden para cancelar
cualquier orden pendiente.

Esto libra a la entidad Cliente de una buena parte de la logica
necesaria para inhabilitarlo. Se corre el riesgo de terminar con una
clase anemica pero lo contrario tambien es riesgoso. Una clase como
Cliente generalmente termina haciendo demasiado. Me pasa ahora mismo
en el trabajo con una clase Contrato. Empiezas tratando de encapsular
toda la logica del contrato alli y al final te das cuenta de que la
has cargado demasiado. Dado que estamos asumiendo el caso en que
Factura es el Root de su propio Aggregate, tiene sentido que el
Cliente se libere de algunas resposabilidades.

Confieso que comence escribiendo esto pensado que elimiar la
asociacion y hacerlo todo desde el Application Service no era lo
mejor. Creo que al escribir llego a la siguiente "conclusion":

1) Si Cliente, Factura y Orden son parte del mismo Aggregate donde
Cliente es el root, entonces solo tenemos un repositorio y no hay
mucho que pensar. Cuando inflemos al Cliente inflamos tambien sus
Facturas y Orden (tal vez con alguna forma de lazy-loading).
2) Si Cliente, Factura y Orden no son parte del mismo Aggregate
entonces es mejor eliminar la asociaion entre Cliente y Factura y
dejar que el Application Service se encargue de la logica de chequear
las facturas y cancelar las ordenes. Siendo Aggregates distintos el
Cliente no tiene ninguna responsabilidad sobre la Factura y las
Ordenes.
3) Si por alguna razon se decide dejar la asociacion creo que seria
logico dejar que Cliente use el RepositorioFactura para devolver *sus*
facturas. Realmente me estoy inclinando por 2).

Bueno di una gran vuelta para no llegar a ninguna parte. Al menos en
mi mente hice algunas aclaratorias importantes. ;)

Lionel.

On Jul 9, 2:08 am, Cristian Prieto <kement...@gmail.com> wrote:
> En el caso particular donde Cliente sea tu Root Aggregate el repositorio
> puedes accederlo en dos lugares :
> 1. En un Domain Service, en dado caso la operación "Inactivar cliente" sea
> suficientemente compleja como para necesitar uno (en este caso no la siento
> compleja como para separarla)
> 2. En un Application Service, que como recordaran guarda la implementación o
> la lógica orientada al uso inmediato de cliente. De igual manera yo no
> tendría repositorios separados de Ordenes de compra o Facturas, ya que estas
> estarían aglutinadas a Cliente (su root aggregate).
>
> Un caso particular podría ser que Cliente ahora posee responsabilidades
> adicionales, es totalmente normal, por eso es un "Domain Object" (recuerden,
> un Domain Object encapsula la "lógica del negocio" y son excelentes para
> casos donde la lógica suele cambiar con el tiempo), se me ocurren solamente
> un par de casos o lógica encapsulada en Cliente:
>
> - Inactivar cliente (a quien inactivas? al cliente!)
> - Agregar una nueva Orden de Compra (a quién se la agregas? al cliente!)
> - Agregar una nueva Factura (a quién se la agregas? al cliente!)
>
> Alguien podría preguntarme: AJA! pero el proceso de *crear* una factura es
> algo complejo, es ahí donde entran las Factories de dominio... Es
> interesante porque Factura y Orden de compra *también* deberían ser Domain
> Objects.
>
> No sobrevaluo la experiencia del cliente, me es TOTALMENTE necesaria...
> nadie sabe más de su negocio que el, y si el lo maneja de esa manera no soy
> nadie para decirle como hacerlo... ¿Hay acoplamiento? no, para eso tenemos
> sobradas formas de evitarlo....
>
> Saludos a todos,
>
> -- Cristian
>
> 2010/7/8 <daniel.cal...@gmail.com>
>
>
>
> > Hola Cristian
>
> > Me da la sensacion que las responabilidades de cliente se han
> > sobrevaluado....
> > Si bien no hay modelos correctos o incorrectos, ya que en definitiva el
> > modelo es una astraccion del dominio segun la visión del observador que
> > construye ese modelo, lo que si sucede es que muchas veces el resultado del
> > modelado es un poco perverso.
> > En este caso que el inhabiltarse sea responsabilidad del propio cliente no
> > parece respetar EXPERTO en INFORMACION, el resultado es acoplamiento y una
> > consecuencia es que se sigue agregando complejidad a la clase Cliente.
> > Tal vez la pregunta existe como consecuencia de esto.
>
> > Solo una mirada sobre el tema, tantas veces me olvide de modelar algo ...
> > :))
>
> > Daniel Calvin
>
> > Enviado desde mi BlackBerry de Movistar (http://www.movistar.com.ar)
> > ------------------------------
> > *From: * Cristian Prieto <kement...@gmail.com>
> > *Sender: * altnet-...@googlegroups.com
> > *Date: *Wed, 7 Jul 2010 21:28:33 -0600
> > *To: *<altnet-...@googlegroups.com>
> > *ReplyTo: * altnet-...@googlegroups.com
> > *Subject: *Re: [altnet-hispano] Re: DDD - acceder a repositorios desde
> > entidades
>
> > Jorge,
>
> > Algo que repito e insisto cada vez que hablamos de DDD: Todo se basa en el
> > modelado del dominio y el lenguaje ubicuo... Lo demás es el simple uso de
> > los patrones expuestos en el libro de Evans... En otras palabras, si bien la
> > mayoría de las veces no "haces" DDD si usas los patrones...
>
> > En el caso particular que expones con el caso de Cliente, Facturas y
> > Órdenes de Compra necesito aclarar que para la mayoría de los dominios (ojo,
> > un dominio depende del dueño del dominio, ya sea empresa, consultor, el
> > chato que te explica el negocio... etc) luciría algo así:
>
> >    - Cliente, Factura y Órdenes son *entidades*
>
> > Y qué pasa cuando quieres desactivar a Cliente? recordemos que según lo que
> > me dices un cliente al desactivarse NO debe tener facturas no pagadas y
> > órdenes en tránsito... Si tu preocupación es la interacción entre los
> > repositorios basta con entender la definición de repositorio de Evans (que
> > difiere ligeramente de la que conocemos de Fowler):
>
> > "*Un repositorio es una colección en memoria que contiene Root Aggregates"
> > *
> > [Ojo, como se daran cuenta estoy "parafraseando" a Evans.]
>
> > El secreto es simple, la palabra *Root Aggregates*, son simplemente
> > entidades centrales que contienen otras entidades o Value Objects. Un
> > repositorio *jamás* retornará Value Objects. Un repositorio puede, pero
> > bajo casos especiales, retornar no Root Aggregates.
>
> > En el caso en particular del Cliente, Factura y Órdenes, el cliente es tu
> > root aggregate. También es importante que una entidad no debe ser anémica y
> > por lo tanto debe contener comportamiento (a esto se le llama Domain
> > Object), una forma de resolver tu problema es el siguiente:
>
> >    - Tu Cliente contiene una colección de Facturas y Órdenes de compra
> >    - Tu Cliente posee un método llamado "Inactivar"
> >    - No hay forma de inactivar un cliente a menos que se llame al método
> >    inactivar (en este caso vez que Cliente contiene comportamiento, no
> >    solamente datos)
> >    - El método "Inactivar" de Cliente busca si tiene Facturas no pagadas y
> >    Órdenes de compra que esten en curso, si es así tira una excepción de
> >    validación o la que te sea más descriptiva
> >    - La entidad Cliente no puede obtenerse de ninguna otra forma más que
> >    usando RepositorioCliente
>
> > Quizás mi ejemplo esta algo "escueto" pero estoy abierto a comentarios :)
>
> > Cristian Prieto
>
> > 2010/7/7 Jorge Rowies <jorge.row...@gmail.com>
> >> 2010/7/7 Carlos Peix <carlos.p...@gmail.com>
>
> >> Hola Lionel,
>
> >>> Yo creo que hay una diferencia en lo que planteo Gustavo y lo que vos
> >>> interpretas (si les entiendo bien a ambos).
>
> >>> Si un objeto accede a otro (o a otros) mediante una referencia que
> >>> almacena en una variable de instancia, estamos bien. En cambio, si un objeto
> >>> debe recurrir a un repositorio para encontrar otro objeto por algun criterio
> >>> determinado, entonces el primer objeto tiene una responsabilidad que no le
> >>> corresponde.
>
> >>> Espero que esto clarifique
>
> >>> ----------------------------------
> >>> Carlos Peix
>
> >>> 2010/7/7 Lionel Orellana <lione...@gmail.com>
>
> >>> Eso seria como no tener asociaciones de ningun tipo. Las
> >>>> responsabilidades pueden estar muy bien separadas y todavia tener
> >>>> relaciones entre las entidades. No entiendo muy bien tu punto.
>
> >>>> Lionel.
>
> >>>> On Jul 7, 6:35 am, Gustavo Ringel <gustavo.rin...@gmail.com> wrote:
> >>>> > El problema no es si se accede a datos o no de otro repositorio, el
> >>>> problema
> >>>> > es responsabilidades. En general una entidad que es el estado de un
> >>>> objeto,
> >>>> > es dudoso que tenga que saber como afectar/obtener el estado de otro
> >>>> > objeto.
>
> >>>> > Gustavo.
>
> >>>  --
> >>> Has recibido este mensaje porque estás suscrito al grupo "AltNet-Hispano"
> >>> de Grupos de Google.
> >>> Para publicar una entrada en este grupo, envía un correo electrónico a
> >>> altnet-...@googlegroups.com.
> >>> Para anular tu suscripción a este grupo, envía un correo electrónico a
> >>> altnet-hispan...@googlegroups.com<altnet-hispano%2Bunsubscribe@go oglegroups.com>
> >>> Para tener acceso a más opciones, visita el grupo en
> >>>http://groups.google.com/group/altnet-hispano?hl=es.
>
> >>  --
> >> Has recibido este mensaje porque estás suscrito al grupo "AltNet-Hispano"
> >> de Grupos de Google.
> >> Para publicar una entrada en este grupo, envía un correo electrónico a
> >> altnet-...@googlegroups.com.
> >> Para anular tu suscripción a este grupo, envía un correo electrónico a
> >> altnet-hispan...@googlegroups.com<altnet-hispano%2Bunsubscribe@go oglegroups.com>
> >> Para tener acceso a más opciones, visita el grupo en
> >>http://groups.google.com/group/altnet-hispano?hl=es.
>
> >  --
> > Has recibido este mensaje porque estás suscrito al grupo "AltNet-Hispano"
> > de Grupos de Google.
> > Para publicar una entrada en este grupo, envía un correo electrónico a
> > altnet-...@googlegroups.com.
> > Para anular tu suscripción a este grupo, envía un correo electrónico a
> > altnet-hispan...@googlegroups.com<altnet-hispano%2Bunsubscribe@go oglegroups.com>
> > Para tener acceso a más opciones, visita el grupo en
> >http://groups.google.com/group/altnet-hispano?hl=es.
>
> > --
> > Has recibido este mensaje porque estás suscrito al grupo "AltNet-Hispano"
> > de Grupos de Google.
> > Para publicar una entrada en
>
> ...
>
> read more »

Lionel Orellana

unread,
Jul 9, 2010, 7:29:40 AM7/9/10
to AltNet-Hispano
Muy buena tu aclaratoria Carlos. Pero no estoy seguro de una de las
conductas que mencionas sobre los Aggregates, en particular "que deben
persistirse en forma completa, nunca por partes". Esto es algo que me
ha dado muchos dolores de cabeza. En el trabajo terminamos por
permitirlo pero sin mucha conviccion. Tienes alguna referencia en el
libro de Evans o en alguna otra parte sobre esto?

Gracias.

Lionel.
> 2010/7/8 Jorge Rowies <jorge.row...@gmail.com>
>
>
>
> > Totalmente de acuerdo Cristian, te agradezco mucho a vos y a todos los
> > demás toda la información que han compartido, la verdad que es de muchisima
> > ayuda.
>
> > Mil gracias!!
>
> > 2010/7/8 Cristian Prieto <kement...@gmail.com>
>
> >> Yep, es por eso que en mi primer correo aclaré algo:
>
> >> *"**En el caso particular que expones con el caso de Cliente, Facturas y
> >> Órdenes de Compra necesito aclarar que para la mayoría de los dominios (ojo,
> >> un dominio depende del dueño del dominio, ya sea empresa, consultor, el
> >> chato que te explica el negocio... etc) luciría algo así:"*
>
> >> De hecho debo confesarlo, armé la clase de cliente *de esa forma* para
> >> tratar de responder una pregunta específica y por la que creo que comenzó
> >> esta thread:
>
> >> *¿Deben mis entidades consumir o tener acceso al repositorio de otra
> >> entidad?*
> >> *
> >> *
> >> Bueno, creo que quedó claro que para mi en este caso específico: *no
> >> directamente*
> >> *
> >> *
> >> La siguiente pregunta que quise ayudar a responder (pero quizás no lo
> >> logré... que se yo...)
>
> >> *Bien, y si tengo muchas entidades quien llama al repositorio de quien y
> >> como hago si el caso cliente necesita desactivarse....*
> >> *
> >> *
> >> Y bueno, fue ahí donde nació la idea de presentarles a nuestro amigo los
> >> Root Aggregates :)
>
> >> Pero como diría nuestro amigo Fabio,
>
> >> Qué se yo, salgo muy poco!!!
>
> >> -- Cristian
>
> >> 2010/7/8 Jorge Rowies <jorge.row...@gmail.com>
>
> >> Cristian, está claro que DDD no son los patrones, sinó que va mucho mas
> >>> allá, pero yo no diría que lo demás es el "simple" uso de los patrones...
> >>> hay complejidad en aplicarlos correctamente y, en gran parte, del hecho que
> >>> los apliquemos correctamente dependerá que nuestro modelo sea escalable,
> >>> mantenible, testeable, etc...
>
> >>> Tal como menciona Daniel, creo que todo depende de las responsabilidades
> >>> que le querramos dar a nuestras entidades, y la única forma de determinar
> >>> esto es estudiando el dominio.
>
> >>> Quizás mi error es tratar de responder un problema que depende del
> >>> dominio con un ejemplo totalmente aislado de la información que provee el
> >>> estudio de un dominio de negocio. Quizás para un dominio determinado está
> >>> bien que Cliente tenga una lista de Facturas y Ordenes y quizás para otro
> >>> dominio, esto traiga mas problemas que ventajas...
>
> >>> Saludos
>
> >>> 2010/7/8 Cristian Prieto <kement...@gmail.com>
>
> >>> Jorge,
>
> >>>> Algo que repito e insisto cada vez que hablamos de DDD: Todo se basa en
> >>>> el modelado del dominio y el lenguaje ubicuo... Lo demás es el simple uso de
> >>>> los patrones expuestos en el libro de Evans... En otras palabras, si bien la
> >>>> mayoría de las veces no "haces" DDD si usas los patrones...
>
> >>>> En el caso particular que expones con el caso de Cliente, Facturas y
> >>>> Órdenes de Compra necesito aclarar que para la mayoría de los dominios (ojo,
> >>>> un dominio depende del dueño del dominio, ya sea empresa, consultor, el
> >>>> chato que te explica el negocio... etc) luciría algo así:
>
> >>>>    - Cliente, Factura y Órdenes son *entidades*
>
> >>>> Y qué pasa cuando quieres desactivar a Cliente? recordemos que según lo
> >>>> que me dices un cliente al desactivarse NO debe tener facturas no pagadas y
> >>>> órdenes en tránsito... Si tu preocupación es la interacción entre los
> >>>> repositorios basta con entender la definición de repositorio de Evans (que
> >>>> difiere ligeramente de la que conocemos de Fowler):
>
> >>>> "*Un repositorio es una colección en memoria que contiene Root
> >>>> Aggregates"*
> >>>> [Ojo, como se daran cuenta estoy "parafraseando" a Evans.]
>
> >>>> El secreto es simple, la palabra *Root Aggregates*, son simplemente
> >>>> entidades centrales que contienen otras entidades o Value Objects. Un
> >>>> repositorio *jamás* retornará Value Objects. Un repositorio puede, pero
> >>>> bajo casos especiales, retornar no Root Aggregates.
>
> >>>> En el caso en particular del Cliente, Factura y Órdenes, el cliente es
> >>>> tu root aggregate. También es importante que una entidad no debe ser anémica
> >>>> y por lo tanto debe contener comportamiento (a esto se le llama Domain
> >>>> Object), una forma de resolver tu problema es el siguiente:
>
> >>>>    - Tu Cliente contiene una colección de Facturas y Órdenes de compra
> >>>>    - Tu Cliente posee un método llamado "Inactivar"
> >>>>    - No hay forma de inactivar un cliente a menos que se llame al
> >>>>    método inactivar (en este caso vez que Cliente contiene comportamiento, no
> >>>>    solamente datos)
> >>>>    - El método "Inactivar" de Cliente busca si tiene Facturas no
> >>>>    pagadas y Órdenes de compra que esten en curso, si es así tira una excepción
> >>>>    de validación o la que te sea más descriptiva
> >>>>    - La entidad Cliente no puede obtenerse de ninguna otra forma más
> >>>>    que usando RepositorioCliente
>
> >>>> Quizás mi ejemplo esta algo "escueto" pero estoy abierto a comentarios
> >>>> :)
>
> >>>> Cristian Prieto
>
> >>>> 2010/7/7 Jorge Rowies <jorge.row...@gmail.com>
> >>>>> 2010/7/7 Carlos Peix <carlos.p...@gmail.com>
>
> >>>>> Hola Lionel,
>
> >>>>>> Yo creo que hay una diferencia en lo que planteo Gustavo y lo que vos
> >>>>>> interpretas (si les entiendo bien a ambos).
>
> >>>>>> Si un objeto accede a otro (o a otros) mediante una referencia que
> >>>>>> almacena en una variable de instancia, estamos bien. En cambio, si un objeto
> >>>>>> debe recurrir a un repositorio para encontrar otro objeto por algun criterio
> >>>>>> determinado, entonces el primer objeto tiene una responsabilidad que no le
> >>>>>> corresponde.
>
> >>>>>> Espero que esto clarifique
>
> >>>>>> ----------------------------------
> >>>>>> Carlos Peix
>
> >>>>>> 2010/7/7 Lionel Orellana <lione...@gmail.com>
>
> >>>>>> Eso seria como no tener asociaciones de ningun tipo. Las
> >>>>>>> responsabilidades pueden estar muy bien separadas y todavia tener
> >>>>>>> relaciones entre las entidades. No entiendo muy bien tu punto.
>
> >>>>>>> Lionel.
>
> >>>>>>> On Jul 7, 6:35 am, Gustavo Ringel <gustavo.rin...@gmail.com> wrote:
> >>>>>>> > El problema no es si se accede a datos o no de otro repositorio, el
> >>>>>>> problema
> >>>>>>> > es responsabilidades. En general una entidad que es el estado de un
> >>>>>>> objeto,
> >>>>>>> > es dudoso que tenga que saber como afectar/obtener el estado de
> >>>>>>> otro
> >>>>>>> > objeto.
>
> >>>>>>> > Gustavo.
>
> ...
>
> read more »

Cristian Prieto

unread,
Jul 9, 2010, 12:16:38 PM7/9/10
to altnet-...@googlegroups.com
Lionel:

Si, el mismo Evans con su definición de repositorios donde indica que es quien maneja la persistencia de Agregados inmediatamente limita que no puedes usar un repositorio para persistir partes del agregado. O como textualmente lo menciona Evans en su libro:

"First we need an abstraction for encapsulating references within the model. An AGGREGATE is a cluster of associated objects that we treat as a unit for the purpose of data changes. Each AGGREGATE has a root and a boundary. The boundary defines what is inside the AGGREGATE. The root is a single, specific ENTITY contained in the AGGREGATE. The root is the only member of the AGGREGATE that outside objects are allowed to hold references to, although objects within the boundary may hold references to each other. ENTITIES other than the root have local identity, but that identity needs to be distinguishable only within the AGGREGATE, because no outside object can ever see it out of the context of the root ENTITY."

Y con respecto a su acceso esto es lo que nos cita Evans:

"For each type of object that needs global access, create an object that can provide the illusion of an in-memory collection of all objects of that type. Set up access through a well-known global interface. Provide methods to add and remove objects, which will encapsulate the actual insertion or removal of data in the data store. Provide methods that select objects based on some criteria and return fully instantiated objects or collections of objects whose attribute values meet the criteria, thereby encapsulating the actual storage and query technology. Provide REPOSITORIES only for AGGREGATE roots that actually need direct access. Keep the client focused on the model, delegating all object storage and access to the REPOSITORIES."

Ahora, hace un tiempo Evans dio una charla de lo que había aprendido después del libro (que ya tiene más de 5 años) y dijo que el capítulo de Repositories volvería a hacerlo, en base porque terminó siendo algo "overrated" por los developers y lectores (creo que sin pensar dos veces podríamos decir que aunque nadie suele relacionar specifications con DDD, muchos relacionan Repository con DDD [y hasta llegan a pensar que implementarlo transforma magicamente su aplicación a una DDD]). Evans, y posteriormente Dahan, sostienen que los Agregados dependen del contexto y no son una entidad todopoderosa que contendrá a todas las demás, así pues, como en el ejemplo anterior Cliente es nuestro agregado, en otro contexto podría serlo Factura y hasta Orden de compra... quién sabe :)

Bien señores, me ha gustado como se ha llevado la discusión, teniamos tiempo no nos sentabamos a filosofar :)

Saludos a todos y un abrazo!


-- Cristian


2010/7/9 Lionel Orellana <lion...@gmail.com>

Carlos Peix

unread,
Jul 9, 2010, 5:51:24 PM7/9/10
to altnet-hispano
Hola Lionel,

Me gustaria aclarar que cuando dije persistencia me referia a un nivel mas abstracto que lo ue hace un ORM. Quise hablar mas bien de "almacenar" o "guardar".

En el ejemplo de Factura e ItemFactura, siempre debe persistirse el agregate completo aunque modifiquemos solo un dato de un item. Incluso hemos hablado (bah, le conte alguna vez) con el Tano que seria ideal que el concepto de "version" de NH se modificara por igual ante la modificacion de cualquiera de sus elementos. Algo asi como un campo "version" para todo el aggregate.

Como contra ejemplo podria decirte que deberiamos evitar levantar un ItemFactura desde la base de datos, mocificarlo y persistirlo sin tocar la factura.

Yo tambien he tenido problemas con la persistencia pero, siempre se ha debido a aggregates demasiado grandes o mal definidos.

----------------------------------
Carlos Peix

2010/7/9 Lionel Orellana <lion...@gmail.com>

Lionel Orellana

unread,
Jul 9, 2010, 7:04:18 PM7/9/10
to AltNet-Hispano
Ah eso es exactamente lo que estaba pensando.

Tambien se puede pensar por ejemplo en un Application Service que
modifica solo parte de la Factura (talvez CancelarItemFactura). El
servicio utilizaria el repositorio para obtener la factura y decirla a
la Factura que cancele el Item en cuestion. El ORM probablemente
termine haciendo un solo query para actualizar el Item pero desde el
punto de vista del servicio hemos modificado la Factura completa.

El hecho de que el ORM te pormite hacer actualizaciones en las
entidades sin necesidad de llamar al repositorio hace las cosas un
poco menos claras.


On Jul 10, 7:51 am, Carlos Peix <carlos.p...@gmail.com> wrote:
> Hola Lionel,
>
> Me gustaria aclarar que cuando dije persistencia me referia a un nivel mas
> abstracto que lo ue hace un ORM. Quise hablar mas bien de "almacenar" o
> "guardar".
>
> En el ejemplo de Factura e* *ItemFactura, siempre debe persistirse el
> agregate completo aunque modifiquemos solo un dato de un item. Incluso hemos
> hablado (bah, le conte alguna vez) con el Tano que seria ideal que el
> concepto de "version" de NH se modificara por igual ante la modificacion de
> cualquiera de sus elementos. Algo asi como un campo "version" para todo el
> aggregate.
>
> Como contra ejemplo podria decirte que deberiamos evitar levantar un
> ItemFactura desde la base de datos, mocificarlo y persistirlo sin tocar la
> factura.
>
> Yo tambien he tenido problemas con la persistencia pero, siempre se ha
> debido a aggregates demasiado grandes o mal definidos.
>
> ----------------------------------
> Carlos Peix
>
> 2010/7/9 Lionel Orellana <lione...@gmail.com>

Nelo Pauselli

unread,
Jul 10, 2010, 10:02:06 AM7/10/10
to altnet-...@googlegroups.com
Buenas... respecto a:

"es responsabilidad de Cliente devolver sus Facturas. El codigo que


utiliza la clase Cliente no tiene por que saber de donde salieron esas
Facturas, simplemente se las pide al Cliente."

¿alguien vio la película "La invención de la mentira"?... no es gran
cosa el film, pero hay una escena donde el sistema de un banco está
caído y como todo el mundo decía la verdad (hasta ese momento) le
preguntan al Cliente cuanta plata tiene en la cuenta y le dan el
dinero en función de eso.

Me da la sensación que estamos pensando mucho en C# y no lo suficiente
en representar el negocio real.

¿que empresa le pregunta al cliente si tiene facturas vencidas antes
de inactivarlo? quizás nos está faltando un actor o quizás simplemente
sea un proceso que debemos modelar.

Saludos.
Nelo.


2010/7/9 Lionel Orellana <lion...@gmail.com>:

Carlos Peix

unread,
Jul 10, 2010, 10:17:55 AM7/10/10
to altnet-hispano
Si, eso pense tambien pero objetar eso era ir demasiado lejos del motivo original del post.

----------------------------------
Carlos Peix

2010/7/10 Nelo Pauselli <nelopa...@gmail.com>

Lionel Orellana

unread,
Jul 10, 2010, 6:07:26 PM7/10/10
to AltNet-Hispano
jeje. Asumo que estamos programando clases honestas y bien
intencionadas.

Pero en todo caso una de las opciones planteadas fue quitar la
coleccion de Facturas del cliente. Tal vez eso modele mejor la
realidad, mentiras y todo. ;)

On Jul 11, 12:02 am, Nelo Pauselli <nelopause...@gmail.com> wrote:
> Buenas... respecto a:
>
> "es responsabilidad de Cliente devolver sus Facturas. El codigo que
> utiliza la clase Cliente no tiene por que saber de donde salieron esas
> Facturas, simplemente se las pide al Cliente."
>
> ¿alguien vio la película "La invención de la mentira"?... no es gran
> cosa el film, pero hay una escena donde el sistema de un banco está
> caído y como todo el mundo decía la verdad (hasta ese momento) le
> preguntan al Cliente cuanta plata tiene en la cuenta y le dan el
> dinero en función de eso.
>
> Me da la sensación que estamos pensando mucho en C# y no lo suficiente
> en representar el negocio real.
>
> ¿que empresa le pregunta al cliente si tiene facturas vencidas antes
> de inactivarlo? quizás nos está faltando un actor o quizás simplemente
> sea un proceso que debemos modelar.
>
> Saludos.
> Nelo.
>
> 2010/7/9 Lionel Orellana <lione...@gmail.com>:
Reply all
Reply to author
Forward
0 new messages