Muchas gracias por sus comentarios! Sí, el become ya me parecía una mala idea por lo que he leído.
Saludos. El 13 de enero de 2011 08:48, Esteban Lorenzano <[email protected]>escribió: > hola, > bueno, me meto en el thread :) > IMHO, el problema es que seguís pensando tu estructura de datos en > relacional, no en objetos (por eso lo pensás como una estructura de datos y > no como un grafo de objetos, je). > Yo la primer pregunta que me haría es "para qué quiero la colección de > todas las facturas? las necesito, o es solo que 'me parece' que tienen que > estar en una colección aparte (como si la colección fuera una tabla)" > realmente me parece que es una instancia muy nueva de tu aplicación (por lo > que veo) para saber si realmente necesitas tener una colección de facturas > aparte. En estos momentos no hay nada que te impida hacer algo como: > > allInvoices > ^self customers > inject: Set new > into: [ :all :each | all, each invoices ] > > eso puede demostrarse no eficiente con el tiempo, pero también puede > demostrarse que no necesitás #allInvoices y entonces te ahorrás todo el > problema de mantener invoices en dos lugares. > Si pese a todo decidís que sí necesitas mantenerlo aparte, lo que te > recomiendo es lo mismo que te recomendó Andrés, y le agrego que, para borrar > facturas, hagas algo como: > > Customer>>removeInvoice: anInvoice > self invoices remove: anInvoice. > IndexadorDeFacturas instance remove: anInvoice. > > usar el become (forward o no), suele no ser una respuesta correcta. Entre > otras cosas porque te hace un scan de todos los objetos en memoria, en > pharo/squeak, dado que no tienen object table. > > nunca dejes de pensar desde el punto de vista del modelo, olvidate de > pensar en la estructura! > > Saludos, > Esteban > > El 13/01/2011, a las 7:42a.m., andres escribió: > > > Yo personalmente evitaría eso porque: > > > > 1. Estás asumiendo cosas sobre las colecciones que contienen a la > factura. Si el día de mañana se te ocurre cambiar el tipo de colecciones y > esas colecciones por algún motivo no pueden contener nils las rompés. > > 2. Tenés que redefinir el protocolo de colecciones para manejar tus casos > ad-hoc (ej. si tenés un array el #size ya no te sirve; tenés que hacer > (select:[..| noNil]) size). > > 3. Estás asumiendo que nadie mas referencia a la factura (ej. un > inspector, un reporte, un histórico de facturas, etc). Si así fuera rompés > todo. > > 4. Como regla genérica el #become no se debe usar para resolver problemas > de diseño; eso te lleva a una seguidilla de hackasos. Mejor es definir > alguien que sepa sincronizar bien las colecciones de facturas. Por ejemplo, > podés definir que el indexador global de facturas no puede agregar o > eliminar facturas, sólo el cliente lo hace. Entonces te queda: > > > > (private) IndexadorDeFacturas>>agregarFactura: unaFacura > > self factuas add: > unaFactura. > > > > (public) Cliente>>agregarFactura: unaFacura > > self factuas add: unaFactura. > > IndexadorDeFacturas instance > agregarFactura: unaFacura. > > > > Si uno es lo suficientemente disciplinado como para no usar el protocolo > privado del indexador de facturas ya no hay problemas. > > > > IMHO es mucho menos esfuerzo hacer ese diseño que todo el quilombo que te > trae el become. > > > > HTH, > > Andrés > > > > Gastón Dall' Oglio escribió: > >> Hola gente. > >> Capaz es una burrada pero bueno, no me quiero quedar con las dudas. > >> Supongamos que tengo unaFactura que esta referenciada desde una > colección > >> perteneciente a un cliente (sus facturas) y también desde una colección > de > >> todas las facturas. Para el tema de resolver el "borrado en cascada" > puedo > >> hacer algo como: > >> unaFactura become: nil > >> 1) Esto me asegura que ya nadie la referencia, y será liberada. > >> 2) Ambas colecciones quedan con la misma cantidad de elementos, solo que > >> ahora tienen una referencia a nil. Que exista una factura nil es fácil > de > >> ignorar con un #select: o permanente con un #removeAll: > >> 3) El tiempo normal que demora un #become: aumenta considerablemente por > >> tratarse de objetos persistidos por Magma. > >> Saludos! > >> El 12 de enero de 2011 18:40, Hernán Morales Durand < > >> [email protected]> escribió: > >>> Hola Gerard, > >>> > >>> El día 12 de enero de 2011 10:59, gerard <[email protected]> escribió: > >>>> Lo que hecho de menos es una "manera de hacer" estandar que prevenga > >>>> que uno haga algunas cosas no del todo recomendables... Aunque sean > >>>> objetos no deja de ser una BD, y seguro que pudes hacer algunas > >>>> animaladas espectaculares sólo por no tener claro un concepto. > >>>> > >>> Hay un texto muy bueno que se llama algo como "Objectivity: Hitting > >>> the relational wall", te va a servir para lo conceptual. > >>> > >>>> Otro ejemplo, yo guardo como root un Dictionary. Tengo definidas unas > >>>> clases "Entity", que al arrancar la imagen Smalltalk se aseguran, cada > >>>> una por separado, de que en ese diccionario exista una entrada con el > >>>> mismo nombre de la clase y una OrderedCollection. Eso lo hice con la > >>>> idea de que automáticamente ya existiera una colección vinculada a > >>>> cada clase Entity... pero ahora veo que quizás eso es una tontería y > >>>> que sería perfectamente válida una instancia root que tuviera un > >>>> montón de colecciones, una por cada entidad. Por otro lado veo algunos > >>>> ejemplos o screencast de Magma que usan el otro sistema: una entrada > >>>> en un diccionario por cada entidad. > >>>> > >>> Es preferible que el objeto raíz sea un objeto de "primera clase" > >>> (Mundo, Fabrica, etc). Como dijiste, dentro de ese objeto pueden > >>> existir varias variables de instancia nombradas que podés hacer > >>> colecciones. Magma no te hace problemas si agregas nuevas variables de > >>> instancia a ese objeto raíz. > >>> > >>>> En fin, me gustaría que todas las clases-entidades tuvieran un > >>>> comportamiento homogeneo. En un ORM, al generarse el código, sé que > >>>> una relación 1:N me va a generar una clase con una colección y una > >>>> serie de métodos estandard, para añadir un elemento a la colección, o > >>>> eliminarla etc Es decir un comportamiento general, dependiendo de las > >>>> relaciones. > >>>> > >>>> ¿Y grandes volúmenes de datos? > >>> ¿Cuanto es grande? En el caso de Magma es casi obligatorio hacer > >>> índices, analizar las consultas que vas a tener, las profundidades de > >>> tus objetos y en base a eso escribir ReadStrategies razonables para > >>> tus requerimientos. Magma aguanta índices de hasta 4096 bits, pero > >>> pasando los 128-bits son un dolor de cabeza si tenés millones de > >>> objetos (en mi caso tengo 20 millones). Lo normal es que trabajes con > >>> índices de 32 o 64 a 128 bits (fijate que tienen que ser múltiplos de > >>> 8). Más bits en los indices, más reducidos los resultados de un > >>> #where:, y menos escaneo lineal del #select: posterior, pero más > >>> procesamiento por cada objeto. > >>> > >>>> Si tienes una lista inmensa de > >>>> facturación y debes de empezar a patearte los items para obtener las > >>>> facturas de un determinado cliente como lo haces? Por un lado podrias > >>>> hacer que cada cliente tuviera su propia colección de facturas, con lo > >>>> que podrías ir directamente a la colección de facturas del cliente, > >>>> perfecto. Pero ¿y si quiero todas aquellas facturas creadas el último > >>>> més sea cual sea el cliente? Entonces ya no tiene sentido acudir a las > >>>> colecciones de facturas de los clientes, sería más trabajoso; debería > >>>> ir a una lista "general" de facturas y empezar a seleccionar las que > >>>> estan en el rango de fechas correcto; es decir, debo tener una > >>>> colección de facturas y otras colecciones parciales de facturas en > >>>> cada cliente. > >>> Lo de las colecciones maestras grandes es una costumbre del mundo > >>> relacional, los programadores relacionales se acostumbran a usarlas > >>> furiosamente, en vez de dispersarlas en el dominio en colecciones más > >>> chicas que no son tan violentadas. Esto no significa que tenés que ir > >>> a hacer 40 colecciones chicas, y en todo casi si lo hacés, la > >>> performance viene cambiando la indexación, pero es una opción para > >>> reducir complejidad. > >>> > >>> Una opción interesante es que podés usar #where: y persistir los > >>> resultados, es decir, los MagmaReaders, en otra MagmaCollection y esto > >>> te daría consultas predefinidas. Lo bueno es que si persistís un > >>> Reader y agregás más objetos a la colección original luego, es decir, > >>> a la cual le hiciste el #where:, los objetos agregados van a aparecer > >>> la próxima vez que enumeres el Reader. Pero antes de enumerar un > >>> Reader entero (no te lo recomiento tampoco, es mejor cuando lo usás > >>> para resultados paginados) tenés que revisar la profundidad de los > >>> objetos que van a ser consultados y hacerte una ReadStrategy > >>> apropiada. Fijate en MagmaCollectionTester>>#testPersistentReader > >>> > >>>> Podría ir más lejos en el ejemplo y plantear varias > >>>> entidades a las que les interesaría tener su propia relación con las > >>>> facturas... Bien: ahora el usuario quiere eliminar una factura, y > >>>> cuando lo haga debo de ser muy consciente de todas las colecciones > >>>> donde puede estar ubicada esa factura para poder eliminarla "bien". > >>>> Debo ir a la lista de facturas del cliente, a la lista general de > >>>> facturas que he mencionado etc etc Veo muy complicado no dejarse > >>>> ningún cabo suelto. No me refería tanto a que pasara el GC, que > >>>> realmente da igual, sino a la posibilidad de dejarse instancias que ya > >>>> no deberian estar, de ahí la comparación con el ON DELETE ACTION. > >>>> > >>> Las consultas tambien pueden ser objetos, y como tales pueden ser > >>> persistidas. Fijate si lo de arriba te sirve. Si tenés problemas de > >>> performance, usá un Message spy. Si no tenés problemas, escribí como > >>> si nada pasara :) > >>> > >>> Saludos > >>> > >>> > >>>> No sé si me he expresado bien. > >>>> > >>>> Saludos. > >>>> > >>>> > >>>> > >>>> On 12 ene, 14:11, Facundo Vozzi <[email protected]> wrote: > >>>>> Hola, > >>>>> Mariano ya te respondió casi todo, para agregar algo, podés leer > sobre > >>>>> algunos enfoques de persistencia (incluído Magma) en el libro de > >>> Seaside:http://book.seaside.st/book/advanced/persistency. > >>>>> Vas a ver que hablan de persistencia basada en Imagen, que es solo > eso > >>>>> guardar la imagen con una global que apunte a tu root (un singleton, > por > >>>>> ejemplo). Después cambiar a que se persista con Magma o Goods es casi > un > >>>>> tramite para GemStone tenés que laburar un cacho más. > >>>>> > >>>>> Respecto de las relaciones, los delete cascade, triggers y cualquier > >>> yerba > >>>>> de la BD relacional tenés que hacer lo siguiente: OLVIDARTE. Para > usar > >>> una > >>>>> base de objetos y sacarle provecho tenés que hacer tu módelo lo más > >>>>> orientado a objetos que te salga y no preocuparte por problemas de > otro > >>>>> paradigma. Quedate tranquilo que vas a tener otros problemas para > >>> resolver > >>>>> :-P pero, simplemente, no los mismos. > >>>>> > >>>>> Saludos, > >>>>> Facu > >>>>> > >>>>> 2011/1/11 gerard <[email protected]> > >>>>> > >>>>> > >>>>> > >>>>> > >>>>> > >>>>> > >>>>> > >>>>>> Buenas. estoy realizando una pequeña aplicación, sólo con propósito > de > >>>>>> pruebas, para trabajar con una base de datos orientada a objetos. > Como > >>>>>> solo quería hacer unas pocas pruebas me he decantado por Magma y > >>>>>> Pharo. > >>>>>> Ahora bien, mi problema es que dudo sobre la manera en que deben > >>>>>> hacerse según que cosas cuando guardas datos como objetos. > >>>>>> 1. Relaciones 1:N. Por ejemplo, una temporada de fútbol tiene varias > >>>>>> jornadas, correcto? Es lógico pensar que cada objeto temporada > debería > >>>>>> de tener una colección de objetos jornada. Ahora bien, cada objeto > >>>>>> jornada debería tener una referencia a su tempoarada no? bien, al > >>>>>> menos en algunos ORMs lo he visto. > >>>>>> 2. Al eliminar, por ejemplo, una temporada, deberíamos tener en > cuenta > >>>>>> que debemos cargarnos tambien aquellas jornadas que pertenecen a esa > >>>>>> temporada, y a su vez todos los partidos etc etc lo que vendría a > ser > >>>>>> una ON DELETE CASCADE de las BBDD relacionales... > >>>>>> Básicamente da la sensación de que sería relativamente fácil en un > >>>>>> momento dado dejar datos inconsistentes en la BD, o que en volúmenes > >>>>>> de datos grandes a la hora de patearse una colección inmensa la > demora > >>>>>> sería muy grande... o que no tienes según que automatismos, cómo los > >>>>>> triggers, para asegurarte que suceda algo al añadir un nuevo > registro > >>>>>> etc etc > >>>>>> Finalmente, ¿existe algún manual de "buenas prácticas" con DB de > >>>>>> objetos? > >>>>>> Saludos y gracias por la ayuda. > >>>>>> -- > >>>>>> To post to this group, send email to [email protected] > >>>>>> To unsubscribe from this group, send email to > >>>>>> [email protected]<clubsmalltalk%[email protected]> > <clubsmalltalk%[email protected]<clubsmalltalk%[email protected]> > > > >>> <clubsmalltalk%[email protected]<clubsmalltalk%[email protected]> > <clubsmalltalk%[email protected]<clubsmalltalk%[email protected]> > > > >>>>>> http://www.clubSmalltalk.org > >>>> -- > >>>> To post to this group, send email to [email protected] > >>>> To unsubscribe from this group, send email to > >>> [email protected]<clubsmalltalk%[email protected]> > <clubsmalltalk%[email protected]<clubsmalltalk%[email protected]> > > > >>>> http://www.clubSmalltalk.org > >>> > >>> > >>> -- > >>> Hernán Morales > >>> Information Technology Manager, > >>> Institute of Veterinary Genetics. > >>> National Scientific and Technical Research Council (CONICET). > >>> La Plata (1900), Buenos Aires, Argentina. > >>> Telephone: +54 (0221) 421-1799. > >>> Internal: 422 > >>> Fax: 425-7980 or 421-1799. > >>> > >>> -- > >>> To post to this group, send email to [email protected] > >>> To unsubscribe from this group, send email to > >>> [email protected]<clubsmalltalk%[email protected]> > <clubsmalltalk%[email protected]<clubsmalltalk%[email protected]> > > > >>> > >>> http://www.clubSmalltalk.org > >>> > > > > -- > > To post to this group, send email to [email protected] > > To unsubscribe from this group, send email to > [email protected]<clubsmalltalk%[email protected]> > > > > http://www.clubSmalltalk.org > > -- > To post to this group, send email to [email protected] > To unsubscribe from this group, send email to > [email protected]<clubsmalltalk%[email protected]> > > http://www.clubSmalltalk.org > -- To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] http://www.clubSmalltalk.org
