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

Responder a