Si, ahora me di cuenta y tenes razón. Perdón si parece abrumadora la otra
explicación

El 21 de enero de 2010 07:54, Carlos Peix <[email protected]> escribió:

> Hola Jose,
>
> Estoy de acuerdo con vos, solo me gustaria que releas el primer post de
> Edgar.
>
> Puedo equivocarme pero entendi que el recien esta empezando con este tipo
> de diseño y juzgue que proponer un patron visitor lo asustaria o le haria
> mas dificil un primer paso. Mucho menos se me ocurriria apuntarlo al blog de
> Udi (con el cual estoy de acuerdo, sobre todo con DomainEvents).
>
> Entiendo que para la mayoria de la audiencia de esta lista mi propuesta
> parece juego de niños pero vale la pena, ya veran cuando dentro de un par de
> años Edgar nos solucione los problemas a nosotros o a otros :-).
>
> De todas maneras esta bueno que tenga alternativas para elegir.
>
> Un abrazo
>
> ----------------------------------
> Carlos Peix
>
> 2010/1/21 José F. Romaniello <[email protected]>
>
> No me gusta esta arquitectura Carlos.
>> Para mi el servicio que lleva a cabo el caso de uso de dar de alta una
>> venta tiene que terminar grabando una venta con su repositorio. Tal vez el
>> movimiento de stock, es un agregado de la misma venta, pero para este caso
>> voy a suponer que no.
>>
>> Hace un tiempo escribí sobre un dominio "parecido" ;)
>>
>> http://jfromaniello.blogspot.com/2009/11/caso-practico-patron-visitor.html
>>
>>
>> Mi idea es que e
>>
>>
>> <http://jfromaniello.blogspot.com/2009/11/caso-practico-patron-visitor.html>
>> public class RegistroDeVentas
>> {
>>
>>    IVisitor<Venta> visitors;
>>
>>    public RegistroDeVentas(IVisitor<Venta>...visitors, IRepositorioVenta
>> repVenta) {
>>    }
>>
>>   public RegistrarVenta(Venta venta)
>>   {
>>     foreach (var visitor in visitors)
>>     {
>>       if(visitor.EsAplicable(venta))
>>           visitor.Aplicar(venta)
>>     }
>>     repVenta.Guardar(venta)
>>   }
>> }
>>
>> La interfaz IVisitor tiene solo esos dos metodos que aparecen ahí, en la
>> configuración del container digo que visitors se aplican para este use
>> case.
>> Un ejemplo de visitor para Movimiento Stock sería
>>
>> public class AplicadorDeStockPorVentas : IVisitor<Venta>
>> {
>>    public  AplicadorDeStockPorVentas(IRepositorioStock repStock){ repStock
>> = ...}
>>    public bool EsAplicable(Venta venta)
>>    {
>>        return venta.TipoDeVenta.MueveStockFisico && venta.EntregaInmediata
>>    }
>>
>>    public void Aplicar(Venta venta)
>>    {
>>      foreach(var linea in venta.Lineas)
>>      {
>>         var movStock = new MovimientoStock(linea.Articulo, linea.Cantidad,
>> Signo.Debito);
>>         repStock.Guardar(movStock);
>>      }
>>    }
>> }
>>
>> Me encanta este tipo de código por que es muy facil testearlo.
>> Si bien en su momento estaba convencido ahora me copa mas la idea de
>> DomainEvents, igual, el código me queda muy similar.
>> Yo uso la misma implementación de Udi, solamente que con ServiceLocator, y
>> en vez de ser todo estática la clase DomainEvents, tengo un IDomainEvents (o
>> IDomainEventsManager el cual inyecto en los servicios)
>> http://www.udidahan.com/2009/06/14/domain-events-salvation/
>>
>>
>> El 21 de enero de 2010 00:13, Carlos Peix <[email protected]>escribió:
>>
>> Hola Edgard,
>>>
>>> Creo que deberias mirar codigo escrito por otros para tener una vision
>>> global. Aunque no adhiero 100% a los detalles de esta arquitectura, podrias
>>> mirar esto: http://code.google.com/p/sharp-architecture/
>>>
>>> No obstante, te dejo aqui algo esquematico (no me critiquen por favor,
>>> abajo aclaro como profesionalizar este codigo :-) ).
>>>
>>> Supongamos que tenes una clase que representa la venta:
>>>
>>> public class Venta {
>>>    IList<LineaVenta> lineas;
>>> }
>>>
>>> y otra que representa a un movimiento de stock
>>>
>>> public class MovimientoStock {
>>>    IList<LineaMovimientoStock> lineas;
>>> }
>>>
>>> Luego se me ocurre una suerte de servicio o de componente cuya
>>> responsabilidad sea aplicar la venta contra el stock:
>>>
>>> public class AplicadorDeVentaAStock {
>>>    public MovimientoStock AplicarVenta(Venta venta) {
>>>       // aqui va la logica por la cual se aplica la venta y se CREA
>>>       // un objeto MovimientoStock
>>>
>>>       return movimientoStock;
>>>    }
>>> }
>>>
>>> Como veras, hasta aqui no hay nada de persistencia, solo logica de
>>> negocio.
>>>
>>> Veamos ahora como interviene la persistencia: seguramente un usuario
>>> presionara un boton cuando quiere grabar la venta, en el codigo de ese boton
>>> deberia llamarse a un objeto (un servicio o fachada de aplicacion) cuya
>>> responsabilidad sea registrar la venta:
>>>
>>> public class RegistroDeVentas {
>>>
>>>    public void Registrar(Venta venta) {
>>>       MovimientoStock movimientoStock
>>> = aplicadorDeVentaAStock.AplicarVenta(venta);
>>>
>>>       repositorioVenta.Save(venta);
>>>       repositorioMovimientoStock.Save(movimientoStock);
>>>    }
>>> }
>>>
>>> Es sencillo no? la version real no tiene que ser mas compleja pero creo
>>> que es necesario dar algunas pautas y aclaraciones.
>>>
>>> De donde salen aplicadorDeVentaAStock, repositorioVenta
>>> y repositorioMovimientoStock en el metodo Registrar? es aqui donde aparece
>>> injeccion de dependencias o DI, no voy a configurar todo eso pero si voy a
>>> sugerir el contructor de la clase RegistroDeVentas:
>>>
>>> public class RegistroDeVentas {
>>>
>>>    IAplicadorDeVentaAStock aplicadorDeVentaAStock;
>>>    IRepositorioVenta repositorioVenta;
>>>    IRepositorioMovimientoStock repositorioVenta;
>>>
>>>
>>> public RegistroDeVentas(IAplicadorDeVentaAStock aplicadorDeVentaAStock,
>>>                                         IRepositorioVenta
>>> repositorioVenta,
>>>
>>>  IRepositorioMovimientoStock repositorioVenta) {
>>>
>>>       this.aplicadorDeVentaAStock = aplicadorDeVentaAStock;
>>>       this.repositorioVenta = repositorioVenta;
>>>       this.repositorioMovimientoStock = repositorioMovimientoStock;
>>>    }
>>> }
>>>
>>> Estas instancias seran "injectadas" en esta fachada de servicio por un
>>> container, por ejemplo, Windsor.
>>>
>>> Alguno que todavia este despierto notara que use el
>>> tipo IAplicadorDeVentaAStock para el aplicador de stock, esto nos permitira,
>>> dependiendo de las preferencias de nuestro cliente, utilizar distintas
>>> estrategias de aplicacion de stock. Esto es el patron Strategy.
>>>
>>> Por supuesto que tambien debe iniciarse transacciones asociadas a los
>>> repositorios, tambien puede hacerse mediante configuracion.
>>>
>>> Creo que con este esquemas tenes algo sencillo que puede servir para
>>> aclararte el panorama al tiempo que, con las aclaraciones que agregue mas un
>>> poco de investigacion de tu parte llegar a algo bastante profecional,
>>> extensible y testeable.
>>>
>>> Un saludo.
>>>
>>> PD: Pierde Boca, gana River :-(
>>>
>>> ----------------------------------
>>> Carlos Peix
>>>
>>> 2010/1/20 Edgar Ramos <[email protected]>
>>>
>>>> Gracias por los comentarios, antes manejaba toda esta logica con store
>>>> procedures y triggers, hoy requiero hacerlo de la forma correcta,
>>>> Carlos tu punto de vista me ha quedado gustando, algun link donde
>>>> profundizar seria bienvenido
>>>>
>>>>
>>>> saludos
>>>>
>>>> El día 20 de enero de 2010 15:46, Carlos Peix <[email protected]>
>>>> escribió:
>>>> > Diego,
>>>> > Para que veas que soy un caballero: yo no disiento con vos. :-)
>>>> > Por supuesto que Diego tiene razon pero, conceptualmente, lo que
>>>> señala es
>>>> > el equivalente a un store procedure (mas precisamente un trigger)
>>>> escrito en
>>>> > C#.
>>>> > Puede funcionar pero no es recomendable en un diseño nuevo, desde
>>>> cero. Al
>>>> > menos en mi opinion.
>>>> > ----------------------------------
>>>> > Carlos Peix
>>>> >
>>>> > 2010/1/20 Diego Mijelshon <[email protected]>
>>>> >>
>>>> >> Disiento con Carlos respecto de si es _posible_ hacer esto, aunque
>>>> estoy
>>>> >> de acuerdo en que no es un muy buen diseño.
>>>> >> Para lograr algo así, podrías usar un PostInsertEventListener que
>>>> haga la
>>>> >> actualización.
>>>> >> Algo más o menos así (no testeado):
>>>> >> void OnPostInsert(PostInsertEvent @event)
>>>> >> {
>>>> >>   var linea = @event.Entity as Linea;
>>>> >>   if (linea != null)
>>>> >>     @event.Session.CreateQuery("update Producto set Stock = Stock -
>>>> >> :cantidad where Id = :idProducto")
>>>> >>       .SetParameter("cantidad", linea.Cantidad)
>>>> >>       .SetParameter("idProducto", linea.Producto.Id)
>>>> >>       .ExecuteUpdate()
>>>> >> }
>>>> >> Así y todo, estarías usando un event listener, que es una herramienta
>>>> de
>>>> >> infraestructura de NHibernate para un concern específico de negocio,
>>>> lo cual
>>>> >> tiene bastante mal olor.
>>>> >>
>>>> >>    Diego
>>>> >>
>>>> >>
>>>> >> 2010/1/20 Edgar Ramos <[email protected]>
>>>> >>>
>>>> >>> Saludos a todos
>>>> >>>
>>>> >>> Como ejemplo similar el siguiente
>>>> >>>
>>>> >>> Tengo estas entidades, Venta, Linea (detalle de la venta), y
>>>> Producto
>>>> >>> (con su stock), y requiero hacer lo siguiente
>>>> >>>
>>>> >>> Al momento de crear Una venta e ingresar su Detalle (Linea), me
>>>> >>> actualice el stock de cada uno de los productos (de Linea),
>>>> >>> basicamente stock=stock-(cantidad digitada)
>>>> >>>
>>>> >>> Puedo hacer esto ?
>>>> >>>
>>>> >>> Cualquier comentario es bienvenido
>>>> >>>
>>>> >>> Gracias nuevamente
>>>> >>>
>>>> >>> --
>>>> >>> Para escribir al Grupo, hágalo a esta dirección:
>>>> >>> [email protected]
>>>> >>> Para más, visite: http://groups.google.com/group/NHibernate-Hispano
>>>> >>
>>>> >>
>>>> >> --
>>>> >> Para escribir al Grupo, hágalo a esta dirección:
>>>> >> [email protected]
>>>> >> Para más, visite: http://groups.google.com/group/NHibernate-Hispano
>>>> >
>>>> >
>>>> > --
>>>> > Para escribir al Grupo, hágalo a esta dirección:
>>>> > [email protected]
>>>> > Para más, visite: http://groups.google.com/group/NHibernate-Hispano
>>>> >
>>>>
>>>> --
>>>> Para escribir al Grupo, hágalo a esta dirección:
>>>> [email protected]
>>>> Para más, visite: http://groups.google.com/group/NHibernate-Hispano
>>>>
>>>
>>>
>>> --
>>> Para escribir al Grupo, hágalo a esta dirección:
>>> [email protected]
>>> Para más, visite: http://groups.google.com/group/NHibernate-Hispano
>>>
>>
>>
>> --
>> Para escribir al Grupo, hágalo a esta dirección:
>> [email protected]
>> Para más, visite: http://groups.google.com/group/NHibernate-Hispano
>>
>
>
> --
> Para escribir al Grupo, hágalo a esta dirección:
> [email protected]
> Para más, visite: http://groups.google.com/group/NHibernate-Hispano
>
-- 
Para escribir al Grupo, hágalo a esta dirección: 
[email protected]
Para más, visite: http://groups.google.com/group/NHibernate-Hispano

Responder a