Portal    Foro    Buscar    FAQ    Registrarse    Conectarse


Publicar nuevo tema  Responder al tema 
Página 1 de 1
 
 
POO Y Persistencia De Datos
Autor Mensaje
Responder citando   Descargar mensaje  
Mensaje POO Y Persistencia De Datos 
 
Buenos dias nuevamente por aqui exponiendo algunas dudas que tengo con respecto al tema de la POO y la persistencia de datos, tengo una clase CProducto mas o menos de esta forma:


PRIVATE idProducto AS Integer
'Identificador de la seccion a la que pertenece el producto
PRIVATE seccion AS Integer
PRIVATE nombre AS String
PRIVATE precio AS Float
'Estas variables tienen que ver con la conexion a la BD
PRIVATE mRs AS Result
PRIVATE mBase AS Connection

PUBLIC SUB _new(ip AS Integer, is as Integer,nom as String, p as Float)
  idProducto=ip
  seccion=is
  nombre=nom
  p=precio
END

PUBLIC SUB getIdProducto() AS Integer
  RETURN idProducto
END


PUBLIC SUB getSeccion() AS Integer
  RETURN seccion
END

PUBLIC SUB getNombre() AS String
  RETURN nombre
END

PUBLIC SUB getIdProducto() AS Float
  RETURN precio
END

PUBLIC SUB Abrir(Bd AS Connection)

 mBase = Bd
 mRs = mBase.Exec("Select * FROM Producto")

END SUB

PUBLIC SUB BuscarPorId()
  
  mRs = mBase.Exec("Select * FROM Producto where idProducto=&1", idProducto)
  Leer()
  
END SUB

PUBLIC SUB buscarPorNombre()
  
  mRs = mBase.Exec("Select * FROM Producto where nombre=&1", nombre)
  Leer()
  
END

PUBLIC SUB grabar()
  
  TRY mBase.Exec("Insert into Producto(seccion,nombre,precio) values(&1,&2,&3)", seccion, nombre, precio)
   IF ERROR THEN
      Message.Error(Error.Text)
   ELSE
      Message.Info("Operacion de insercion exitosa")
   END IF
    
END SUB

PRIVATE SUB Leer()
 
 IF mRs.Available THEN
  idProducto = mRs["idProducto"]
  seccion = mRs["seccion"]
  nombre = mRs["nombre"]
  precio = mRs["precio"]
 END IF

END SUB

PUBLIC FUNCTION getProductos() AS Result

 RETURN mBase.Exec("Select * FROM Producto order by nombre")

END FUNCTION

PUBLIC FUNCTION buscarPorSeccion() AS Result
  
  RETURN mBase.Exec("Select * FROM Producto where seccion=&1", seccion)
  
END FUNCTION
 


Lo que quisiera saber es si es correcto trabajar el tema de la base de datos en la misma clase, osea búsqueda, inserción, modificación y eliminación de datos, o si es necesario trabajarla en otra clase relacionada unicamente con la conexión y en esta dejamos solo las propiedades y los metodos propios de la misma, ahora yo he creido conveniente crear una variable mBase de tipo Connection para abrir la conexion a la BD, cuyos parametros los especifico a la hora de crear el objeto en la interfaz grafica, tambien tengo una variable llamada mRs de tipo Result para manejar los valores obtenidos de la BD. El tema es que he manejo los parametros de Conexion a la base de datos en un modulo llamado Conexion que es de la siguiente forma:

PUBLIC miConex AS Connection

PUBLIC FUNCTION ConectarBase() AS Boolean
  
  miConex = NEW Connection
  TRY miConex.Close
   miConex.Type = "mysql" 'Tipo de la base de datos
   miConex.Host = Variables.CFG_BD_HOST
   miConex.Login = Variables.CFG_BD_USUARIO
   miConex.Password = Variables.CFG_BD_PASS
   IF Variables.CFG_BD_NEW THEN
      miConex.Open()
      IF NOT miConex.Databases.Exist(Variables.CFG_BD_NAME) THEN
         miConex.Databases.Add(Variables.CFG_BD_NAME)
         miConex.Name = Variables.CFG_BD_NAME
      ENDIF  
      miConex.Close()  
   END IF
   miConex.Name = Variables.CFG_BD_NAME
   miConex.Open()
   RETURN TRUE
  CATCH
   Message.Error(Error.Text)  
   RETURN FALSE  

END

PUBLIC SUB CerrarConexion()
  
  IF miConex = NULL THEN RETURN 'Si no hay conexion se sale inmediatamente de la funcion
  miConex.Close() 'Cerrar la conexion
  miConex = NULL 'Hacer nulo el objeto de conexion
  
END

PUBLIC SUB RellenaCombo(lRs AS Result, lCampo AS String, Objeto AS ComboBox)

 DIM i AS Integer
 DIM Total AS Integer
 Objeto.Clear()
 IF lRs.Available THEN
    lRs.MoveFirst
    Total = lRs.Count
    FOR i = 0 TO Total - 1
        Objeto.Add(CStr(lRs[lCampo]))
        lRs.MoveNext
    NEXT
 END IF
 lRs = NULL
 IF Objeto.Count > 0 THEN Objeto.Index = 0

END SUB

PUBLIC SUB RellenarGridView(dbLista AS GridView, lRs AS result, lTotalColumna AS Integer, lAnchoA AS Variant, lTituloA AS Variant, lCampos AS Variant)
 
   DIM i, j AS Integer
   DIM fil AS Integer
   DIM col AS Integer
   dbLista.rows.count = 0
   IF NOT IsNull(lRs) THEN
     IF lRs.Available AND lRs.Count <> 0 THEN
       dbLista.columns.count = lTotalColumna
       dbLista.rows.count = lRs.count
       FOR i = 0 TO lTotalColumna - 1
        dbLista.Columns[i].Width = lAnchoA[i]
        dbLista.Columns[i].Text = lTituloA[i]
       NEXT
       DO WHILE lRs.Available
         FOR col = 0 TO lTotalColumna - 1
            dbLista[fil, col].Text = lRs[lCampos[col]]              
         NEXT
         fil = fil + 1
         lRs.MoveNext()
       LOOP
     END IF
   END IF

END SUB

PUBLIC SUB RellenaListBox(lRs AS Result, lCampo AS String, Objeto AS ListBox)

 Objeto.Clear
 FOR EACH lRs
  Objeto.Add(Trim(lRs[lCampo]))
 NEXT
 IF Objeto.Count > 0 THEN
  Objeto[0].Selected = TRUE
 END IF
 
END SUB
 


En la interfaz gráfica luego de crear el objeto de tipo CProducto, uso la variable producto y manejo la conexion de la siguiente forma:
producto.Abrir(Conexion.miConex)
 


Mi duda como ya lo dije anteriormente es por el tema de manejar correctamente la POO y la persistencia de datos, quisiera que me den mas luces sobre esto.
Saludos y gracias de antemano.
 



 
inkarri - Ver perfil del usuarioEnviar mensaje privadoVisitar sitio web del usuario 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: POO Y Persistencia De Datos 
 
Hola

Me pierdo un poco con todo ese código que pones así que te lo explico telegráficamente con un ejemplo de una aplicación en la que quieres gestionar unos clientes.

Siempre ir de lo general a lo particular.

De esta manera desde nuestra aplicación llamar a un único formulario de clientes (date cuenta que un formulario es una clase). Desde la aplicación general la única forma de gestionar clientes de una forma u otra es llamar a ese formulario.

Ese formulario muestra información general de clientes y da opciones. Si eliges una opción llegas a otro formulario que ofrece una información y posibilidades mas concretas. Recalco de nuevo que un formulario es una clase.

Ese posible que en ese segundo nivel aún ofrezcas opciones que permitan concretar aún mas en un tercer nivel la información de clientes.

Con esto puedes establecer una capa de presentación en la que dispones de unos formularios debidamente conectados entre sí para ofrece al usuario las opciones requeridas de clientes. Esa es la capa de presentación o la capa de usuario como quieras.

Sin embargo con esa capa solo muestras información y ofreces opciones. El usuario elegirá una opción y en ese momento tienes que hacer cálculos o realizar una acción en base de datos o lo que sea. De nuevo el principio de lo general a lo particular pero ahora ya no usar formularios. Estas en la segunda capa que el usuario no ve pero que hace cosas. En esa segunda capa tu creas una clase clientes donde realizas las operaciones y cálculos que tus formularios necesitan. Esas operaciones serán algunas cálculos aritméticos por ejemplo, otras de comunicaciones y otras de bases de datos. El mismo principio de antes, de lo general a lo particular. En esa primera clase de clientes pones las rutinas mas generales (por ejemplo verificación de datos válidos y llamadas a funciones generales (por ejemplo insertar, modificar, borrar), sin embargo es posible que necesites llamadas a funciones mas específicas. Sin som muchas o complejas podría aconsejar un tercer nivel de clases que realicen esas operaciones. Por ejemplo si en la clase de clientes tienes una función de insertar cliente y por alguna razón la inserción de clientes es algo extremadamente complejo te creas una clase para getionar las inserciones de clientes y punto. Normalmenten o hará falta pero podría ser.

Aun hay al menos una capa mas. Hay operaciones que son comunes a clientes y proveedores. Por ejemplo si quieres logear las operaciones tanto tendrás que logear unas que otras. Estas van en otra capa de funciones con un alto nivel de abstracción y que realizan tareas comunes tanto para clientes como para proveedores. Para ello creas una clase logear y en ella metes rutinas que permitan logear algo sea lo que sea ese algo. Así las llamas desde clientes o desde proveedores y hacen su trabajo.

No pienses en términos: voy a hacer una clase para accesos a base de datos para clientes. Eso es un error. Si pensamos en ir de lo general a lo particular y nos centramos en clientes las tareas normales para gestionar clientes son altas, bajas, consultas, modificaciones. Que para ello uses bases de datos o sockets o lo que sea es circunstancial.

La persistencia
El caso es que desde tus formularios tu envías parámetros a tus clases para que hagan su trabajo. Ellas hacen cosas y envían parámetros a otras clases para que hagan el suyo. Algunos de esos datos no requieren persistencia. Declaras una clase a nivel local, le pasas los parámetros adecuados, te quedas con el resultado y punto. Cuando la función termine la clase que declaró será liquidada.

Sin embargo hay cosas que debieran ser persistentes. Por ejemplo si estableces una conexión a base de datos o una conexión a un socket no debieras abrirlo y cerrarlo cada vez. La declaración de los datos debe realizarse en el nivel en el que deben existir y enviarse como parámetros  a los formularios y clases.

Ejemplo
Yo quiero definir una única conexión a bd que me sirva para toda mi aplicación esté donde esté. Para ello en el form inicial declaro la conexión a nivel de módulo

mas tarde en el sub main o donde sea realizo la conexión
Cn=Conectar()

Ahora ya está conectada y funciona a nivel de formulario. Si el usuario elige una opción que le abre otro formulario lo que haré es pasarle como parámetro esa conexión.
public sub opcion_click
Dim F as new formulario_Clientes(Cn) 'el envío la conexión
F.show


y con eso se carga el formulario de clientes y en él está declarada una variable para recibir esa conexión. Fíjate que no pones el NEW porque no vas a instanciar una nueva sino que vas a recibir una que ya existe.
private Cn as connection '
public sub _new(CnRecibida as connection
Cn=CnRecibida
end

Ahora ya tienes en tu formuario específico de clientes la conexión que abriste. Cuando cierres este formulario la conexión continuará existiendo en el general y si el usuario pulsa otra cosa igualmente se le pasará la conexión como parámetro. Es probable que este otro formulario también ofrezca opciones u utilice clases y tendrás que pasarle igualmente la conexión.

De esta forma tu puedes crear un objeto persistente (una conexión a base de datos a un socket o lo que sea) y pasarlo como parámetro a las clases que necesites.

Osea que como tu siempre trabajas de lo general a lo particular declaras las variables en el lugar que les corresponden por su nivel y las pasas como parámetros a sus hijos.

Perdón por la parrafada. Espero haberte contestado bien.
 



 
soplo - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: POO Y Persistencia De Datos 
 
Citar:

Lo que quisiera saber es si es correcto trabajar el tema de la base de datos en la misma clase, osea búsqueda, inserción, modificación y eliminación de datos, o si es necesario trabajarla en otra clase relacionada unicamente con la conexión y en esta dejamos solo las propiedades y los metodos propios de la misma


Citar:

Mi duda como ya lo dije anteriormente es por el tema de manejar correctamente la POO y la persistencia de datos, quisiera que me den mas luces sobre esto.


En un entorno de objetos la persistencia, idealmente, debe ser transparente. La POO y el uso de base de datos relacionales no tienen nada ver una con la otra desde un punto de visto tecnológico. Por lo tanto, no se puede entender correctamente el enfoque de la persistencia de la tecnología de objetos al usar bases de datos relacionales.

En entornos empresariales se utilizan frameworks que mapean los objetos a BD relacionales y viceversa (ORM). Un framework ORM es un adaptador entre dos tecnologías incompatibles (POO y BD relacionales).

Para entender el enfoque de la persistencia desde la tecnología de objetos es necesario estudiar Smalltalk, entender qué es un ambiente de objetos "vivos" y una imagen de objetos. Bueno, se puede entender también con otros lenguajes/plataformas que cuenten con características similares (Java, C#) pero generalmente requieren de frameworks adicionales, mientras que en Smalltalk es nativo y por otra parte Smalltalk es "el" lenguaje/entorno de objetos.

También es necesario aprender a usar bases de datos de objetos (ODBMS).

Respecto de la otra parte de tu pregunta, cómo manejás las conexiones depende del tipo de aplicación.

Si la aplicación tendrá una gran cantidad de usuarios concurrentes que provocarán un ataque intensivo contra el motor de la base de datos, seguramente las conexiones serán un recurso escaso y probablemente no te convenga tener una conexión abierta desde que inicia la ejecución de tu aplicación hasta que termina. En esos casos se realiza un pool de conexiones, cada conexión se asigna dinámicamente a quien la necesite y se libera tan pronto como sea posible para que quede a disposición de otros usuarios. No creo que este sea tu caso.

Si tu aplicación será usada por unos pocos usuarios podés tranquilamente abrir una conexión apenas se inicia su ejecución y cerrarla cuando la ejecución de tu aplicación termina.

Cómo manejar los objetos relativos al manejo de la BD (connection, result, etc), no está mal que lo hagas con módulos, pero si querés entender más sobre POO, no sigas usando módulos, sino sólo clases y aprende patrones de diseño.

Si necesitás tener mayor flexibilidad podés aplicar el patrón Data Access Object (DAO). Esto resulta útil si existen buenas posibilidades de que necesites cambiar la base de datos que usarás o incluso pasar a usar un framework ORM.
 




===================
Cómo programar con Gambas

Speed Books: informática libre.
 
fabianfv - Ver perfil del usuarioEnviar mensaje privadoVisitar sitio web del usuario 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: POO Y Persistencia De Datos 
 
Voy a tomar en cuenta las sugerencias brindadas tan amablemente por uds muchas gracias, mi intencion con esto es tratar de escribir los programas con la mayor calidad y buenas practicas de programacion que me sean posibles, no se si en gambas hay ya definidas algunas buenas practicas a seguir tal como las tiene Java o C# para guiarnos de estas y estandarizar un poco mas el uso y la masificacion de este lenguaje tan interesante.
Saludos y gracias nuevamente.
 



 
inkarri - Ver perfil del usuarioEnviar mensaje privadoVisitar sitio web del usuario 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: POO Y Persistencia De Datos 
 
Escribí un ejemplo básico de una gestión de clientes en este enlace.

Enlace

quizá te sirva.

 
 



 
soplo - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Mostrar mensajes anteriores:    
 

Publicar nuevo tema  Responder al tema  Página 1 de 1
 

Usuarios navegando en este tema: 0 registrados, 0 ocultos y 1 invitado
Usuarios registrados conectados: Ninguno


 
Lista de permisos
No puede crear mensajes
No puede responder temas
No puede editar sus mensajes
No puede borrar sus mensajes
No puede votar en encuestas
No puede adjuntar archivos
Puede descargar archivos
No puede publicar eventos en el calendario



  

 

cron