Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 26-02-2008
Avatar de AzidRain
[AzidRain] AzidRain is offline
Miembro Premium
 
Registrado: sep 2005
Ubicación: Córdoba, Veracruz, México
Posts: 2.914
Poder: 21
AzidRain Va camino a la fama
Solicito su opinión sobre mi modelado

Desde siempre me ha gustado la cosa esta del OOP sin embargo miles de topes me he dado al tener que modelar modelos (válgase la expresión) E-S en OOP. Como ya sabemos nuncan cuadra al 100%. No quiero usar eso de ECO porque sabe como a .NET (ni lo mande Dios) ni de cosas raras por ahí. Casi siempre me encuentro con el siguiente problema:

Tenemos una ventana que muesta digamos las facturas pendientes por registrar en la contabilidad (de entrada nace TFactura que puede tener a su vez TCliente y TPartidas así como muchas propiedades más). Bien, como TFactura es en realidad un registro de una BD y a su vez lo son TCliente y TPartidas (este último es el detalle de la tabla facturas hablando en términos de BD). De entrada para mostrar todas las facturas lo mas simple es hacer un query y mostrarlo en una tabla, pero coño, entonces donde ha quedao nuestra TFactura. Pensé en una TCollection de TFacturas pero entonces para que coño esta TDataset y los componentes DBAware de Delphi???.
Lo que hice es esto:

Modelé una TFactura y demás parafernalia. TFactura recibe una conexión a la BD para recuperar el contenido de cada registro y almacernarlo en sus propiedades, digamos que cada propiedad tiene que que ver con un campo de la BD. Ahora bien, las partidas, ah las partidas. Bueno, yo lo que hices es darle una propiedad Partidas a TFactura que es en realidad un TClientDataset para crear una tabla en memoria la cual TFactura es capaz de llenar a partir de la tabla de detalle de la BD y a su vez guardar en la BD.

De esta forma puedo usar digamos una rejilla para mostrar el detalle de TFactura usando componentes dbAware. Claro que para la actualización de la BD sí utilizo comandos SQL como INSERT o UPDATE según el caso. Digamos que TFactura sabe como guardarse en la BD y como guardar su "detalle" en la misma BD. De tal suerte que para guardar la factura solo llamo a TFactura.Save quien a su vez llama a SaveDetail quien se encarga de guardar el detalle de la factura.

Los constructores normalmente los hago pasádole a la clase una conexión a la BD que utilizo: TFactura.Create(ZMyConnection) (uso Zeos)


He notado que un efecto adicional es que dejo totalmente independiente la BD de mi modelo de objeto, de manera que si hay excepciones las puedo manejar dentro de mi clase principal sin llegar a la BD más que cuando ya se ha validado casi todo.

Me hubiera gustado prescindir por completo de componentes dbaware pero esto requiere mucho más código y terminaría haciendo cosas al estilo Java y en Delphi se supone que todo se puede hacer mucho más rápido.

Comentarios:¿Es un modelado adecuado? ¿Se me ha pasado algo? ¿Mejor le cambio?
__________________
AKA "El animalito" ||Cordobés a mucha honra||
Responder Con Cita
  #2  
Antiguo 26-02-2008
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Cita:
Empezado por AzidRain Ver Mensaje
Casi siempre me encuentro con el siguiente problema:

Tenemos una ventana que muesta digamos las facturas pendientes por registrar en la contabilidad (de entrada nace TFactura que puede tener a su vez TCliente y TPartidas así como muchas propiedades más). Bien, como TFactura es en realidad un registro de una BD y a su vez lo son TCliente y TPartidas (este último es el detalle de la tabla facturas hablando en términos de BD). De entrada para mostrar todas las facturas lo mas simple es hacer un query y mostrarlo en una tabla, pero coño, entonces donde ha quedao nuestra TFactura. Pensé en una TCollection de TFacturas pero entonces para que coño esta TDataset y los componentes DBAware de Delphi???.
Eso precisamente es una de las tantas preguntas que me hago yo.

Cita:
Empezado por AzidRain Ver Mensaje
Lo que hice es esto:

Modelé una TFactura y demás parafernalia. TFactura recibe una conexión a la BD para recuperar el contenido de cada registro y almacernarlo en sus propiedades, digamos que cada propiedad tiene que que ver con un campo de la BD. Ahora bien, las partidas, ah las partidas. Bueno, yo lo que hices es darle una propiedad Partidas a TFactura que es en realidad un TClientDataset para crear una tabla en memoria la cual TFactura es capaz de llenar a partir de la tabla de detalle de la BD y a su vez guardar en la BD.
De esta forma puedo usar digamos una rejilla para mostrar el detalle de TFactura usando componentes dbAware. Claro que para la actualización de la BD sí utilizo comandos SQL como INSERT o UPDATE según el caso.
Hasta allí creo que logro entenderte.

Cita:
Empezado por AzidRain Ver Mensaje
Digamos que TFactura sabe como guardarse en la BD y como guardar su "detalle" en la misma BD. De tal suerte que para guardar la factura solo llamo a TFactura.Save quien a su vez llama a SaveDetail quien se encarga de guardar el detalle de la factura.
¡Espera el carro!¿Qué?
Se que no soy un experto en la materia, pero si hay algo que no me gusta mucho es que un objeto de la capa del dominio se meta en la capa de base de datos.
O yo estoy entendiendo mal, amigo... o es que aquí falta aclarar algo.
No es por criticar, pero normalmente, cuando uno menciona TCliente, TFactura, etc..., hace referencia a algo independiente de una base de datos (Si... tu me diras que al final de cuentras se resume en base de datos), y si haces que TFactura tome dicha función estás perdiendo cohesión amigo y aumentando el acoplamiento hacia algo que, en principio, no debería suceder.

Cita:
Empezado por AzidRain Ver Mensaje
Los constructores normalmente los hago pasádole a la clase una conexión a la BD que utilizo: TFactura.Create(ZMyConnection) (uso Zeos)
¿De quien desciende TFactura? Ya estoy confundido.


Cita:
Empezado por AzidRain Ver Mensaje
Me hubiera gustado prescindir por completo de componentes dbaware pero esto requiere mucho más código y terminaría haciendo cosas al estilo Java y en Delphi se supone que todo se puede hacer mucho más rápido.

Comentarios:¿Es un modelado adecuado? ¿Se me ha pasado algo? ¿Mejor le cambio?
Tienes razón al decir que debería hacerse todo más rápido en Delphi, y más fácil... eso lo ofrecen los DataWare... pero también hay que tener presente otras cosas: ¿Porqué hacemos TFactura? ¿Que nos beneficia sino la usamos en otros lados también? A lo que voy amigo, es que como tu sabes emplear dataware es un arma de doble filo, si se emplea mal terminas con un sistema en poco tiempo pero que dificilmente sea reusable, si optamos por seguir un buen uso de objetos... conseguimos aquellas filosóficas ideas que propone la POO pero nos resulta más complicado.

Se que no he dicho algo nuevo, y amigo.. me gustaría poder decirte si haces bien o haces mal... pero si hay algo que le he aprendido, más que nada por los golpes, es que no hay 2 diseños que estén absolutamente bien, y mal.

Me encantaría poder tener algo más visual sobre lo que te estás planteando. No me refiero a código, sino a diagramas, pero eso ¿es pérdida de tiempo no?

No ayudo en nada con lo dicho, pero es que debo admitir que tomaste mi atención al decir que TFactura sabe como debe guardarse en una BD. Lo correcto sería que TFactura delegue el trabajo a alguien a quien sabe de base de datos.

Si puedes darte el tiempo, me gustaría que profundices tus explicaciones. Se que es probable que mis novatas experiencias no aporten demasiado al tema, pero cualquier pedacito que pueda aportar, aquí me tienes.

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #3  
Antiguo 26-02-2008
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.282
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto


Cita:
Empezado por AzidRain Ver Mensaje
...De entrada para mostrar todas las facturas lo mas simple es hacer un query y mostrarlo en una tabla, pero coño, entonces donde ha quedao nuestra TFactura. Pensé en una TCollection de TFacturas pero entonces para que coño esta TDataset y los componentes DBAware de Delphi???.
Hay que pensar que los componentes de Datos estandard de Delphi no están pensados para este modelo de trabajo. Partiendo de esto yo veo dos posibles soluciones.
* Una intentar "adaptar" los componentes de Base de Datos para trabajar con tu objeto TFactura. En mi caso lo he hecho en una ocasión modificando no directamente los componentes sino el Conector. De esta forma nuevo conector es el que se engancha a tu Base de Datos relacional, te recupera datos y los convierte en objetos del tipo TFactura. Con esto y derivando los componentes estandard puedes conseguir que más o menos funcionen con ese modelo. Si no recuerdo mal, este modelo es el que usaban los InstantObjects.
* La otra opción pasa por crear los componentes desde cero. Con esto conseguirás que tus componentes estén del todo orientados al modelo de persistencia, pero eso implica un trabajo muy arduo y con muchas horas de programación.

He programado ambas soluciones (en dos empresas distintas) y te aseguro que la segunda fue un trabajo de muchas horas y la solución enos convincente que la primera.

Cita:
Empezado por AzidRain Ver Mensaje
...De tal suerte que para guardar la factura solo llamo a TFactura.Save quien a su vez llama a SaveDetail quien se encarga de guardar el detalle de la factura.

Los constructores normalmente los hago pasádole a la clase una conexión a la BD que utilizo: TFactura.Create(ZMyConnection) (uso Zeos)
Aquí estoy de acuerdo con Delphius. El tema de Base de Datos deberías independizarlo de tus clases. Para esto normalmente se usa un Objeto independiente que es el que se encarga de todas las conexiones y "conversaciones" con la Base de Datos (Gestor). Lo grande de este modelo es su independencia de la Base de Datos. Si mañana cambias de Base de Datos, basta con cambiar el Gestor para que todo funcione correctamente. El realidad lo que se hace es tener un Gestor y derivarlo para cada BD que necesites. De esta forma tienes un sistema ampliable a distintos mnotores de forma sencilla.

Cita:
Empezado por AzidRain Ver Mensaje
He notado que un efecto adicional es que dejo totalmente independiente la BD de mi modelo de objeto, de manera que si hay excepciones las puedo manejar dentro de mi clase principal sin llegar a la BD más que cuando ya se ha validado casi todo.
Correcto. Supongo que debes contar con algun "diccionario"; La definición de las clases TFactura, TCliente y de todos sus campos.

Cita:
Empezado por AzidRain Ver Mensaje
Me hubiera gustado prescindir por completo de componentes dbaware pero esto requiere mucho más código y terminaría haciendo cosas al estilo Java y en Delphi se supone que todo se puede hacer mucho más rápido.
Como ya te he comentado, conseguir prescindir de todos los componentes de DB y conseguir a la vez una aplicación real solvente y ágil, significa que deberías crear tus propios componentes de trabajo. Eso en un trabajo de muchas horas y además no es trivial.

Por lo demás, a mi entender debes tener claras y bien diferenciadas las partes que forman este modelo. Por un lado tu Base de Datos, por otro lado tu modelo y por otro lado un "Gestor de persistencia" que es el que une los dos anteriores y que los hace independientes. Este gestor es el que te convierte los datos de la BD con un modelo relacional en tus objetos del modelo con una estructura de Objetos.
El "modelo" normalmente está formado por tus objetos (TCliente, TFactura,...) y por un diccionario que mantiene y almnacena la estructura y características de esos objetos.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #4  
Antiguo 26-02-2008
Avatar de AzidRain
[AzidRain] AzidRain is offline
Miembro Premium
 
Registrado: sep 2005
Ubicación: Córdoba, Veracruz, México
Posts: 2.914
Poder: 21
AzidRain Va camino a la fama
En efecto la cuestión de acceder a la BD pretendo dejársela a una clase TGestor del cual pueden descender TGestorFacturas, TGestorClientes, etc. Esta clase por ejemplo sería la que reciba un objeto y lo almacene en la BD y a la inversa lo recupere, busque, etc. Ahorita por cuestiones de tiempo lo he dejado así como les comenté. De hecho cuando haga el cambio solo pasará dos métodos de TFactura al gestor por lo que no preocupa mucho.

Principalmente mi duda de "¿Lo estaré haciendo bien?" radicaba en el uso de TClientDatasets para almacenar temporalmente datos de la BD .Pero creo que no voy tan mal, de hecho me he dado cuenta que aunque dedico 2 o 3 días a modelar, diagramar y demás. Cuando escribo el código generalmente (90%de las veces) funciona a la primera.
__________________
AKA "El animalito" ||Cordobés a mucha honra||
Responder Con Cita
  #5  
Antiguo 26-02-2008
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.282
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por AzidRain Ver Mensaje
...la cuestión de acceder a la BD pretendo dejársela a una clase TGestor del cual pueden descender TGestorFacturas, TGestorClientes, etc.
No va per ahí la cuestión o al menos yo no me refería a eso.
El Gestor es único. Y Las opreciones sobre la Base de Datos debe hacerlas utilizando un diccionario de Datos.

Si tienes 500 Clases tendrás 500 Objetos (que derivarán de la clase base <TObjetoNegocio>) un diccionario de Datos, donde se almacene de alguna manera la estructura de esos 500 objetos. Un único Gestor (que utilizando la información del diccionario debe ser capaz de realizar todas las operaciones sobre Base de Datos -independientemente de los objetos-) y por último las tablas.

En cuanto al tema de TClientDataSet creo que puede ser una opción acertada; Es más, en nuestro caso estuvimos revisándolos y hay dicumentación donde se explica cómo hacerlo (la mayoría referente a modelos de persistencia en Java, pero que explican las líneas generales).
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Solicito recomendación sobre formas de programar Monxy Varios 6 22-04-2007 21:30:17
Opinión sobre un proyecto nuevo. ppb Linux 2 17-01-2007 13:40:25
Vuestra opinión sobre el API XML-RPC de una aplicación dec Internet 32 09-12-2006 21:09:57
Solicito informacion sobre Temporizacion neto57 Varios 0 21-09-2006 03:06:22


La franja horaria es GMT +2. Ahora son las 16:29:43.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi