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
