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 [hidden email] To unsubscribe from this group, send email to [hidden email] http://www.clubSmalltalk.org |
2011/1/11 gerard <[hidden email]> Buenas. estoy realizando una pequeña aplicación, sólo con propósito de No necesariamente. En una verdadera base de objetos creo que eso debería ser indiferente. Si por tu negocio tiene sentido, entonces sí. Sino, no. Además podes pensar en responsabilidades, y no datos. Ponele, yo podría pedirle a una jornada su temporada, pero ésta no está como variable de instancia, sino que hace una búsqueda sobre todas las temporadas para ver quien tiene a dicha jornada. Todo esto para darte un ejemplo.
Acá tenes que tener en cuenta que en Smalltalk no podes borar un objecto. Lo máximo que podes hacer es desreferenciarlo. En tu ejemplo, cuando elimines una temporada, se borrarán todas las referenias a las jornadas. Si algunas de esas jornadas estaba solamente siendo referenciadas por esa temporada, entonces cuando corra el garbage collector se la llevará. Mientras tanto (hasta que venga el GC) no pueden ser accedidas desde ningún otro objecto, así que no pasa nada. El único problema sería si tu código de negocio haría chanchadas como Jornada allInstances pues ahí si todavía estan visibles los objectos (hasta que pase el GC). Pero por lo general las applicaciones tiene roots o objectos donde las cosas están almacenadas. No soles haces un allInstances.
No. No debería haber inconcistencias. o que en volúmenes es cierto que el GC en bases de objectos no es trivial y si, la performance es importante. o que no tienes según que automatismos, cómo los Esto es fácil. Es Smalltalk. Las cosas se resuelven en los objectos. Suponete que quiero trigear algo cuando se agrega una jornada a una Temporada...fácil: Temporada >> addJornada: unaJornada self hacerLoQuiera. self jornadas add: unaJornada Y listo. Bueno, en magma deberías tener un diccionario donde desde algún lugar lleges a la temporada no....
Ni idea. Pero seguramente Smalltalk es de lo más existente en relación a bases de objetos Saludos y gracias por la ayuda. saludos -- -- To post to this group, send email to [hidden email] To unsubscribe from this group, send email to [hidden email] http://www.clubSmalltalk.org |
In reply to this post by gerard alis
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 <[hidden email]> Buenas. estoy realizando una pequeña aplicación, sólo con propósito de To post to this group, send email to [hidden email] To unsubscribe from this group, send email to [hidden email] http://www.clubSmalltalk.org |
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. 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. 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? 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. 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. No sé si me he expresado bien. Saludos. On 12 ene, 14:11, Facundo Vozzi <[hidden email]> 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 <[hidden email]> > > > > > > > > > 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 [hidden email] > > To unsubscribe from this group, send email to > > [hidden email]<clubSmalltalk%[hidden email]> > > >http://www.clubSmalltalk.org -- To post to this group, send email to [hidden email] To unsubscribe from this group, send email to [hidden email] http://www.clubSmalltalk.org |
Que tal Gerard. Mas allá de lo que ya te comentaron, mi humilde aporte
es que no te vuelvas loco con potenciales problemas de performance antes de tiempo. Uno muchas veces trae preconcpetos de otros paradigmas que no aplican en el entorno de trabajo actual. Por ejemplo, en el caso que mencionás de las facturas, tené en cuenta que los objetos se cargan por demanda y, dependiendo de la BDOO, uno puede definir índices. O sea que si en tu modelo te parece correcto que un cliente tenga sus facturas y luego necesitás iterar por todas las facturas entre dos fechas pasando por los clientes, eso no implica que tengas que traer a memoria todas las facturas persistidas. Cuando se levante un cliente sus v.i. seguramente serán proxies a disco y al hacer la consulta lo harás por el índice, por lo que no vas a necesitar traer a memoria instancias que no te sirven. Esto implica que va a ser igual de rápido que hacer un "select" sobre la clase Factura directamente? Seguramente no, va a ser mas lento, pero a lo que apunto es que no te mandes a hacer optimización temprana por cosas que no sabés si van a ser un problema. Respecto del problema de consistencia (i.e. de tener dos colecciones de facturas -la del cliente vs. el listado general- que tienen que estar sincronizadas) fijate que es un problema de diseño, no de persistencia. Ese mismo problema lo tendrías si lo hacés en memoria. En líneas generales deberías intentar evitar ese tipo de cosas, o asegurarte que manejas bien la consistencia, cosa que puede ser simple o complicada dependiendo de lo organizado que seas para programar :). Mis 2 ctvs. Saludos, Andrés gerard 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. > > 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. > > 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? 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. 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. > > No sé si me he expresado bien. > > Saludos. > > > > On 12 ene, 14:11, Facundo Vozzi <[hidden email]> 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 <[hidden email]> >> >> >> >> >> >> >> >>> 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 [hidden email] >>> To unsubscribe from this group, send email to >>> [hidden email]<clubSmalltalk%[hidden email]> >>> http://www.clubSmalltalk.org > -- To post to this group, send email to [hidden email] To unsubscribe from this group, send email to [hidden email] http://www.clubSmalltalk.org |
In reply to this post by gerard alis
2011/1/12 gerard <[hidden email]> Lo que hecho de menos es una "manera de hacer" estandar que prevenga No, no es una BD es una base de objetos no de datos. Lo de hacer "animaladas", y bueno, sí, yo hice un montón y después con la experiencia vas haciendo menos. Creo que si te olvidás de la persistencia y grabás el image es la manera más simple de no pensar orientado a tablas pero bueno, paciencia.
Yo guardo una instancia de "XXXSystem" (un singleton) como root pero se puede guardar, como decís vos, cualquier otra cosa.
Bueno, si querés podés, si te sentís cómodo con eso, podés hacer algo similar no creo que dependa de la persistencia eso. Otra opción es usar los métodos estandar de Collection para hacer eso.
Cada cliente tiene su colección de facturas y cuando consultes un rango de fechas, le pedís a todos tus clientes las facturas, las ordenas y las seleccionás. Cuando eso se ponga lento porque tenés muchas facturas, o mejor dicho, muchos clientes, ahí agregar a tu sistema, o a tu empresa, una collección indexada con todas las facturas (es barato, es solo una referencia más a cada factura). Y sí, tenés que programar ordenadamente la consistencia como dice Andrés.
Podría ir más lejos en el ejemplo y plantear varias Ummm, puede pasar que te olvides de sacarlo de algún lado pero salta con cualquier test. Lo agregás y listo. Debería ser en un solo lugar donde tocar.
Sí, creo que te preguntas cosas porque ya conoces los problemas de otro paradigma y querés anticiparte a todo. Creo que lo mejor, aunque parezca disparatado, es no pensar y solo ponerse a mandar mensajes. Después aparecen solos los problemas y ahí hay que pensar un cacho.
Nos vemos
-- To post to this group, send email to [hidden email] To unsubscribe from this group, send email to [hidden email] http://www.clubSmalltalk.org |
In reply to this post by Mariano Martinez Peck
Mariano
Tengo entendido q allInstances llama primero al gc. por lo menos en Dolphin y Va no recuerdo si squeak . supongo que depende de cada smalltalk . Hasta donde yo se saludos MDC
-- To post to this group, send email to [hidden email] To unsubscribe from this group, send email to [hidden email] http://www.clubSmalltalk.org |
2011/1/12 Juan <[hidden email]> Mariano jejejejjeje justo antes de mandar el mail, le pregunté exactamente lo mismo que vos. Revisé el código y no vi que lo llame. Después hice un: | test | Transcript show: 'TestCase instances: ', TestCase instanceCount asString. test := TestCase new. Transcript show: 'TestCase instances: ', TestCase instanceCount asString. test := nil. Transcript show: 'TestCase instances: ', TestCase instanceCount asString. Smalltalk garbageCollect. Transcript show: 'TestCase instances: ', TestCase instanceCount asString. Y en el workspace vi: TestCase instances:
0TestCase instances: 1TestCase instances: 1TestCase instances: 0 tal vez está mal mi "test"
-- To post to this group, send email to [hidden email] To unsubscribe from this group, send email to [hidden email] http://www.clubSmalltalk.org |
In reply to this post by gerard alis
Hola Gerard,
El día 12 de enero de 2011 10:59, gerard <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> >> >> >> >> >> >> >> >> > 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 [hidden email] >> > To unsubscribe from this group, send email to >> > [hidden email]<clubSmalltalk%[hidden email]> >> >> >http://www.clubSmalltalk.org > > -- > To post to this group, send email to [hidden email] > To unsubscribe from this group, send email to [hidden email] > > 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 [hidden email] To unsubscribe from this group, send email to [hidden email] http://www.clubSmalltalk.org |
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 <[hidden email]> escribió: Hola Gerard, -- To post to this group, send email to [hidden email] To unsubscribe from this group, send email to [hidden email] http://www.clubSmalltalk.org |
In reply to this post by Mariano Martinez Peck
El día 12 de enero de 2011 18:12, Mariano Martinez Peck
<[hidden email]> escribió: > > > 2011/1/12 Juan <[hidden email]> >> >> Mariano >> >>> >>> El único problema sería si tu código de negocio haría chanchadas como >>> Jornada allInstances pues ahí si todavía estan visibles los objectos >>> (hasta que pase el GC). >>> Pero por lo general las applicaciones tiene roots o objectos donde las >>> cosas están almacenadas. No soles haces un allInstances. >> >> Tengo entendido q allInstances llama primero al gc. por lo menos en >> Dolphin Eso es porque el #allInstances sino te puede dar instancias que van a ser reclamadas por el GC, en Squeak/Pharo en cambio sí te puede dar moribundas, asi que siempre conviene mandar un #garbageCollect antes para asegurarte que tenés las activas. Viste como es esto, en Dolphin cuidan al cliente... o trataban por lo menos :) Saludos, Hernán -- To post to this group, send email to [hidden email] To unsubscribe from this group, send email to [hidden email] http://www.clubSmalltalk.org |
In reply to this post by Gastón Dall' Oglio
Hola Gastón,
Sólo para comentar algo, porque de esto se ha escrito mucho ya. En Squeak y Pharo (VW tambien), tenés dos tipos de become, el #become: es bidireccional (llamado two-way) y el #becomeForward: (el one-way) es unidireccional, en VW se llama #oneWayBecome:. #become: nil *nunca* puede ser enviado porque intercambia los objetos receptor y nil (si mal no recuerdo en realidad por adentro sólo intercambia los encabezados de los objetos, pero algunas veces se necesitan intercambiar contenidos... de todos modos tiene uno o dos usos válidos en el ambiente), el receptor va a apuntar a nil y nil va a apuntar al receptor, y como mucho apunta a la nada y la nada ahora es algo y algo es la nada, la nada nueva (el algo) no se puede recolectar más y todo esto más otra serie de eventos lamentables destruyen tu ambiente. #becomeForward: nil solo convierte al receptor en nil, pero no es recomendable utilizarlo (en esta lista capaz te encontrás verdaderos detractores de los become ;). Es usado para mantenimiento muchas veces, pero en contadas ocasiones se necesita realmente, por ej. podés eliminar instancias obsoletas sin usar ningún #becomeForward:. En Magma no podés hacer un #becomeForward:, por lo menos hasta hace un tiempo era así y tal vez hace poco existe el soporte (por lo que vi lo dudo). Pero estimo que hay muchas formas de solucionarlo, la de usar consultas predefinidas es una, particionar las colecciones es otra, creo que Ale Reimondo alguna vez comentó en Smalltalking sobre como solucionar este tipo de problemáticas... si alguien tiene un enlace mejor. Saludos, Hernán El día 13 de enero de 2011 01:02, Gastón Dall' Oglio <[hidden email]> 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 > <[hidden email]> escribió: >> >> Hola Gerard, >> >> El día 12 de enero de 2011 10:59, gerard <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> > 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 [hidden email] >> >> > To unsubscribe from this group, send email to >> >> > >> >> > [hidden email]<clubSmalltalk%[hidden email]> >> >> >> >> >http://www.clubSmalltalk.org >> > >> > -- >> > To post to this group, send email to [hidden email] >> > To unsubscribe from this group, send email to >> > [hidden email] >> > >> > 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 [hidden email] >> To unsubscribe from this group, send email to >> [hidden email] >> >> http://www.clubSmalltalk.org > > -- > To post to this group, send email to [hidden email] > To unsubscribe from this group, send email to > [hidden email] > > http://www.clubSmalltalk.org -- To post to this group, send email to [hidden email] To unsubscribe from this group, send email to [hidden email] http://www.clubSmalltalk.org |
In reply to this post by Gastón Dall' Oglio
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 < > [hidden email]> escribió: > >> Hola Gerard, >> >> El día 12 de enero de 2011 10:59, gerard <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>>> 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 [hidden email] >>>>> To unsubscribe from this group, send email to >>>>> [hidden email]<clubSmalltalk%[hidden email]> >> <clubSmalltalk%[hidden email]<clubSmalltalk%[hidden email]> >>>>> http://www.clubSmalltalk.org >>> -- >>> To post to this group, send email to [hidden email] >>> To unsubscribe from this group, send email to >> [hidden email]<clubSmalltalk%[hidden email]> >>> 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 [hidden email] >> To unsubscribe from this group, send email to >> [hidden email]<clubSmalltalk%[hidden email]> >> >> http://www.clubSmalltalk.org >> > -- To post to this group, send email to [hidden email] To unsubscribe from this group, send email to [hidden email] http://www.clubSmalltalk.org |
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 < >> [hidden email]> escribió: >>> Hola Gerard, >>> >>> El día 12 de enero de 2011 10:59, gerard <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> >>>>>> 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 [hidden email] >>>>>> To unsubscribe from this group, send email to >>>>>> [hidden email]<clubSmalltalk%[hidden email]> >>> <clubSmalltalk%[hidden email]<clubSmalltalk%[hidden email]> >>>>>> http://www.clubSmalltalk.org >>>> -- >>>> To post to this group, send email to [hidden email] >>>> To unsubscribe from this group, send email to >>> [hidden email]<clubSmalltalk%[hidden email]> >>>> 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 [hidden email] >>> To unsubscribe from this group, send email to >>> [hidden email]<clubSmalltalk%[hidden email]> >>> >>> http://www.clubSmalltalk.org >>> > > -- > To post to this group, send email to [hidden email] > To unsubscribe from this group, send email to [hidden email] > > http://www.clubSmalltalk.org -- To post to this group, send email to [hidden email] To unsubscribe from this group, send email to [hidden email] http://www.clubSmalltalk.org |
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 <[hidden email]> escribió: hola, -- To post to this group, send email to [hidden email] To unsubscribe from this group, send email to [hidden email] http://www.clubSmalltalk.org |
Buenas, ya que estamos yo también me meto jeje.
Solo un comentario. Para hacer un buen modelo en la base de objetos lo que quizá deberías hacer es pensar en que tenés un programa en memoria y que nunca se apaga. Es decir, imaginate que vos tenes que hacer un programa que no tiene que persistir nada porque la compu siempre está prendida, Entonces, en ese caso como harías? yo tendría las colecciones que correspondan y agregaría algún diccionario por eficiencia, etc. La consistencia del modelo la tendría que manejar el modelo mismo, asegurandose de poner y sacar las cosas de las colecciones cuando corresponda. No hay ningún trigger mágico ni nada de eso, que viene de otro paradigma. Yo creo que la idea de una base de objetos es justamente esa, hacer lo más transparente posible la persistencia, aunque en realidad haya algunas sutiles diferencias en la práctica... Luego con el tiempo, como ya mencionaron acá, te vas a ir dando cuenta de si hay que hacer alguna "chanchada" o algo para ir optimizando los tiempos. 2011/1/13 Gastón Dall' Oglio <[hidden email]>
-- To post to this group, send email to [hidden email] To unsubscribe from this group, send email to [hidden email] http://www.clubSmalltalk.org |
> Buenas, ya que estamos yo también me meto jeje. Buenas. Yo creo que la lista esta para que todo el que tenga algo que aportar lo haga :) Ya que estamos con el tema base de objetos y de datos, les consulto si alguno sabe que orientación tienen las bases de datos que se encuadran bajo el enfoque nosql. ¿Están tratando de hacer algo orientado a objetos o algo totalmente novedoso?
El 13 de enero de 2011 10:58, Gaboto <[hidden email]> escribió: Buenas, ya que estamos yo también me meto jeje. -- To post to this group, send email to [hidden email] To unsubscribe from this group, send email to [hidden email] http://www.clubSmalltalk.org |
Hasta donde yo tengo entendido, nosql es más que nada como una movida de nuevas propuestas para la persistencia que son novedosas ya que no siguen el modelo relacional. No es un paradigma determinado.
Una base de objetos por ejemplo sería parte del movimiento nosql, pero existe hace mucho más tiempo ;). Pero hay otros modelos, uno por ejemplo consiste en tener una especie de diccionarios con clave valor (creo que era cassandra). 2011/1/13 Gastón Dall' Oglio <[hidden email]>
-- To post to this group, send email to [hidden email] To unsubscribe from this group, send email to [hidden email] http://www.clubSmalltalk.org |
In reply to this post by Gastón Dall' Oglio
Hola gente
Bueno aporto un poco, creo que gaboto dijo algo claro y clave. Tenes que pensar el dominio para modelarlo sin restricciones , lo de la base de datos ,yo y quizas todo el mundo ,no se, lo llamo programacion orientada al modelo de datos. o sea en bases de datos relacionales se programa , los progamas son orientados a la representacion de los datos. Entonces cuando cambias algun tipo de dato o definicion el programa sufre cambios a veces muy grandes. El mapeo es una solucion intermedia. o sea se programa en "objetos" o en lenguajes objetosos, excepto claro esta el smalltalk. y se mapea los "objetos" a la db , teniendo mas o menos exito. En gral cuando se parte de esta formacion se tiende a mapear, una clase una tabla una instancia una row. Ese es el modelo de pensamiento que hay que romper, hay que pensar tu objeto tu parte del modelo que necesita conocer? , las facturas ? ,ok. son muchas ? bueno conocera una coleccion , y cada factura que necesita conocer? , (por conocer digamos ,normalmente lo tiene o lo usa) podes arrancar con un modelo exploratorio , en verdad deberias. y experimentar con los colaboradores ( cosas q conoce otros objetos del dominio) e ir moviendolos agregando sacando etc, hasta que pueda cumplir con su cometido ( el modelo funcione) . Luego pensa en la persistencia, no al reves. lo ultimo. o sea que el modelo ande primero luego la persistencia , asi como tambien te indicaron aqui y por necesidades de perfomance u otras haces las "chanchadas" o sea ensucias a tu modelo. por ensuciar digamos que es la parte donde la persistencia afecta a tu modelo . bueno acoto hasta aca. saludos mdc 2011/1/13 Gastón Dall' Oglio <[hidden email]>
-- To post to this group, send email to [hidden email] To unsubscribe from this group, send email to [hidden email] http://www.clubSmalltalk.org |
Me parece muy superficial la discusiòn.
De partida el modelamiento de base de datos relacionales parte de la idea E. F. Codd (http://www.dcc.uchile.cl/~rbaeza/inf/codd.html) de modelar las dependencias funcionales (http://cs.gmu.edu/~aobaidi/spring-02/Normalization.ppt), que no son otra cosa que pares X -> Y (como un Dictionary o un HashMap). Eso se puede representar directamente en Smalltalk.
La representación E-R y la representación en tablas son sólo el resultado de tratar de convertir las dependencias funcionales en una representación entendible por humanos y por máquinas respectivamente. Lo simpàtico del asunto es que las dependencias funcionales podrìan representarse directamente en Smalltalk sin necesidad de mecanismos intermedios, derivando luego el modelo E-R o el modelo en tablas según sea necesario.
Podrìas tener aplicaciones funcionando, cambiar las dependencias funcionales, y que la aplicación se adapte a los cambios sin necesidad de reprogramar nada ni de detener la aplicación. Para los que tengan dificultades entendiendo lo anterior, serìa factible hacer un generador de còdigo que genere interfaces de usuario, modelo de datos y migrador de datos en forma automática, aunque claramente prefiero que la aplicación no se detenga y siga funcionando sin necesidad de programar nada.
Saludos, Guillermo.
-- 2011/1/13 Juan <[hidden email]> Hola gente -- Saludos cordiales, Guillermo Schwarz Sun Certified Enterprise Architect To post to this group, send email to [hidden email] To unsubscribe from this group, send email to [hidden email] http://www.clubSmalltalk.org |
Free forum by Nabble | Edit this page |