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
