Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Providers (https://www.clubdelphi.com/foros/forumdisplay.php?f=10)
-   -   Datasnap, separando logica de acceso a datos (https://www.clubdelphi.com/foros/showthread.php?t=88300)

AgustinOrtu 17-05-2015 18:27:08

Datasnap, separando logica de acceso a datos
 
Que tal club, resulta que es la primera vez que me encamino en algo "serio" con Datasnap, estoy algo confundido

A grandes rasgos, esta seria mas o menos la forma de trabajar que venia usando hasta ahora:

Para cada objeto del dominio del negocio, encapsulaba toda la logica en una unit especifica para el, por ejemplo:

Código Delphi [-]
unit Productos;

interface

type
  TProducto = class
  public
    Id: int64;
    Descripcion: string;
    // bla bla mas campos
    function Guardar: boolean;
    class function Obtener(const Id: int64): TProducto;
  end

implementation

uses 
  UDataModule;

function TProducto.Guardar: boolean;
begin
  if Id = 0 then
    Result := DataModule.ProductMgr.Nuevo(Self)
  else
    Result := DataModule.ProductMgr.Actualizar(Self);
end;

class function TProducto.Obtener(const Id: int64): TProducto;
begin
  Result := DataModule.ProductMgr.Obtener(Id)
end;

Y ademas tambien generaba una unit especifica para controlar el acceso a datos, por ej:

Código Delphi [-]
unit ProductoMgr;

interface

type
  TProductoMgr = class
  public
    constructor Create(AConnection: TADOConnection);
    function Nuevo(const Producto: TProducto): boolean
    function Actualizar(const Producto: TProducto): boolean;
    function Obtener(const Id: int64): TProducto;
    function Buscar(const Descripcion: string): TDataSet;
  end;

Y luego en el clasico DataModule tenia que declarar en la seccion publica una instancia de cada uno de esos Mgr. En el evento AfterConnect de la Conexion los construia pasandoles como argumento la propia conexion

Bueno, ya se imaginan como funciona, es muy sencillo

Desde el cliente podria hacer cosas como

Código Delphi [-]
var 
  p: TProducto;
  IdRetornado: int64;
begin
  p := TProducto.Create;
  try
    p.Descripcion := 'Mi Producto';
    if p.Guardar then
    begin
      IdRetornado := p.Id;
      ShowMessage('Guardado correctamente'); 
    end else
      ShowMessage('Error');
  finally
    p.Free;
  end;
  
  p := TProducto.Obtener(IdRetornado);
  try
    ShowMessage(p.Descripcion); // 'Mi Producto'
  finally
    p.Free;
  end;
end;

Ahora bien, en datasnap es distinto. Entiendo las limitantes de que no puedo retornar directamente un objeto como mi TProducto, para eso deberia usar Json por ejemplo, esa no es mi duda

Lo que realmente quiero hacer es seguir con la idea de encapsular cada objeto en su unit especifica, pero datasnap requiere que publique cada metodo que los clientes van a invocar en el TServerMethods. Solamente quiero mantender "la casa en orden" y no tener en una sola unit (la del TServerMethods) todos los metodos y funciones que puedo invocar, mas bien me gustaria tener todo separadito y ordenadito en su lugar, me explico?

Existe alguna forma de hacer esto o hay que llenar una sola unit con todos los metodos? :confused:

Saludos

tmsanchez 19-05-2015 12:22:15

Hola.

Estoy iniciando con DataSnap y encontré esta serie de videos de Embarcadero relacionados con Datasnap:

http://www.embarcadero.com/es/rad-in-action/delphi-labs

Probablemente el episodio número 10 "DataSnap - Passing "Plain Old Delphi Objects" Parameters" te siva para lo que comentas.

Saludos.

giulichajari 19-05-2015 21:19:58

Y de donde conociste esa forma de organizar el programa(pregunto nomas), trabajas con orientacion a objetos?.

Yo diria que compruebes todos los campos en los procesos del lado del cliente para mandarle todo "limpio al server". Luego si la logica de negocio iria en tu servidor de capa intermedia realizado en DataSnap.

Y yo para el acceso a datos utilizo componentes ZeosLib... estos se conectan directamente al servidor de base de datos, es decir no uso procedimientos para obtener la lista de productos o de clientes. De esta forma ademas si es servidor de datasnap esta fuera de linea por X motivo pero el servidor de base de datos no... lo mismo se puede conectar a la bd. Igualmente tengo archivos xml del lado del cliente.

No se de que se trata tu aplicacion...

AgustinOrtu 20-05-2015 00:40:52

La idea es usar Firemonkey para que la aplicacion que ya tengo en VCL sea multi plataforma, utilizar las mismas unit de logica de negocio que ya tengo (en el ejemplo de arriba la unit Productos) y que el servidor contenga todo los TxxxMgr (en el ejemplo el TProductoMgr). En realidad necesito poder conectar desde dispositivos moviles, si fuera una Firemonkey de escritorio puedo conectar con Zeos, FireDAC, ADO, tal como decis vos

En la logica defino el objeto en si, que atributos y operaciones pueden realizar, esto deberia ser comun ya sea para una aplicacion VCL o para una Firemonkey.

Luego cada unit de la logica inlcuye en el uses el DataModule principal, y le piden al Mgr correspondiente que inserte, borre, actualice o realice un select, etc

De esa forma al realizar mantenimientos, agregar campos o correciones hago el trabajo una sola ves, con recompilar los binarios de todas las plataformas deberia ser suficiente

Ahora el problema con Datasnap es que cuando se acceden a los ServerMethods, lo que se retorna es una referencia de la clase TServerMethods no una instancia que es lo que yo venia haciendo.

Código Delphi [-]
procedure TServerContainer1.DSServerClass1GetClass(
  DSServerClass: TDSServerClass; var PersistentClass: TPersistentClass);
begin
  PersistentClass := ServerMethodsUnit1.TServerMethods1;
end;

si se busca la definicion del tipo TPersistentClass encontramos esto:

Código Delphi [-]
  TPersistentClass = reference to TPersistent;

Es decir, debemos heredar de TPersistent para poder publicar los metodos (cosa que yo no hacia)

Creo que la solucion es crear varias DSServerClass, en lugar de tener lo que yo llamo un TProductoMgr, tener un DSServerClassProductos por decir algo, que se encarge de publicar los respectivos metodos Get, Update, Save, Insert.. etc

Aunque tambien se podrian poner TODOS los metodos en el TServerMethods que genera el wizard, con el unico inconveniente de que queda todo junto y no separado cada cosa con la suya pero bueno :)

No es en este preciso momento lo mas urgente que tengo para hacer asi que lo voy a dejar momentaneamente de lado, se agradecen los comentarios

Igual, seguramente lo que termine haciendo es, dado que el servidor datasnap es necesario pura y exclusivamente para los dispositivos moviles, implementar los metodos que necesito y chau.. no es la idea que desde el telefono se pueda manejar todo, es mas que nada para sacar algun listado/estadistica/reporte

Saludos!


La franja horaria es GMT +2. Ahora son las 22:24:48.

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