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]>
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


--
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]>

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