Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   No se ejecuta un evento a tiempo (https://www.clubdelphi.com/foros/showthread.php?t=81213)

vani 22-10-2012 15:17:33

No se ejecuta un evento a tiempo
 
Hola a todos.
He diseñado una clase que define un objeto que a su vez tiene una propiedad que es otra clase. Es el caso de una factura de venta que a su vez tiene asociado un cliente. Como después quiero hacer estos objetos persistentes en una base de datos, cada clase tiene una propiedad que es su iD que lo identifica dentro de la base de datos, es decir la clase Tfactura tiene idFactura y la clase Tcliente tiene idCliente. Por supuesto la clase Tfactura tambien tiene una propiedad que es idCliente, que me permite identificar en la factura a que cliente pertenece. Pero como intento trabajar con objetos, la clase Tfactura tiene una propiedad que se llama cliente y es de tipo Tcliente. El hecho es que quiero que a un objeto factura pueda decirle que su objeto cliente es cierto cliente llamando a su propiedad cliente.loadByNombre(nombre) , tal que asi: factura.cliente.loadByNombre(nombre) , o bien asi factura.cliente = clienteyaLeido (clienteyaLeido es un objeto de tipo Tcliente), con lo cual no toco para nada la propiedad idCliente del objeto factura, o sea factura.idCliente, pero necesito que esta propiedad cambie automáticamente en cuanto pase lo anterior, es decir en cuanto cargue o modifique el objeto cliente de la factura. Para todo ello he creado el oportuno evento en la propia clase Tfactura que activo en cuanto el objeto cliente de la misma cambia, lo que ocurre es que ese evento se ejecuta unas veces si y otras no, y creo que no es que no se ejecute, sino que se ejecuta a posteriori de que haga a dicho objeto persistente en la base de datos. Esto lo he averiguado porque si el proceso lo sigo mediante el debug de delphi, cosa que permite dilatar el proceso final, este evento si se ejecuta y el idCliente de factura se registra bien. Sin embargo si el programa lo lanzo sin debug esta propiedad no queda reflejada correctamente.

Espero haber sido lo mas conciso y preciso en el problema y les agradecería que me ayudasen. Si alguien necesita de que sea mas concluyente escribiendo algo del código que me lo indique y así lo haré.

Un Saludo a todos y gracias por prestarme atención.

gatosoft 23-10-2012 18:06:28

Bueno, hay que concentrarse un poco para entender, y nunca está de mas poner algo de código, pues nos ayuda a analizar si el problema es el que describes o es algo que no has visto...

Por otro lado considero que si tienes un objeto TCliente dentro de TFactura, es redundante tener un IdCliente en tu clase factura... pero bueno, eso depende lo que estes haciendo...

El evento que te indica si un cliente cambió no debe originarse desde tu factura, sino desde el mismo TCliente


Código Delphi [-]
Type
  TOnCambioCliente = procedure(IdCliente: Integer) of Object;

TCliente =Class
Private
  FOnCambioCliente : TOnCambioCliente;
public
  Property OnCambioCliente: TOnCambioCliente read FOnCambioCliente write FOnCambioCliente;
  Procedure CargarCliente;
end;

Procedure TCliente.CargarCliente;
Begin
  //cargar el cliente.... 
  if assigned(FOnCambioCliente) then
     FOnCambioCliente(Self.IdCliente);
end;
y en tu clase factura lo debes capturar...

Código Delphi [-]
TFactura= Class
Private
  FIdCliente: Integer;
  FObjetoCliente: TCliente;
Public
  Constructor Create;
  Property idCliente: Integer read FIdCliente;
  Procedure MyOnCambioCliente(IdCliente: Integer);
end;

Constructor TFactura.Create;
Begin
  inherited;
  FObjetoCliente:= TCliente.Create;
  FObjetoCliente.OnCambioCliente:= MyOnCambioCliente;
end;

Procedure TFactura.MyOnCambioCliente(IdCliente: Integer);
Begin
  FIdCliente := IdCliente;
end;
Ahora, como te decia, no me parece natural que tengas un IDCliente en tu TFactura si ya tienes un TCliente asociado... asi que podrías dar acceso a tu cliente desde la factura:

Código Delphi [-]
LaFactura.Cliente.IdCliente ...

O podrias redefinir la propiedad IdCliente de la factura asi:

Código Delphi [-]
TFactura= Class
Private
  FObjetoCliente: TCliente;
  Function GetIdCliente: Integer ;
  Procedure setIdCliente(Value: Integer);
Public
  Property idCliente: Integer read GetIdCliente write setIdCliente;
end;

Function TFactura.GetIdCliente: Integer ;
Begin
  Result:= FObjetoCliente.IdCliente;
end;

Procedure TFactura.setIdCliente(Value: Integer);
Begin
   FObjetoCliente.CargarCliente(Value);
end;

espero que te haya servido...

vani 24-10-2012 12:51:11

De antemano darte las gracias, porque he resuelto el problema perfectamente. La verdad es que me estaba saltando a la torera las normas de encapsulamiento. Por otra parte, has entendido perfectamente el problema y tu solución por supuesto ha sido la adecuada. En cuanto a lo que comentas que no entiendes porqué utilizo el idCliente en la TFactura , comprendo también tu postura si hablamos al cien por cien de objetos, pero no me queda mas remedio que hacer persistente esa propiedad ya que utilizo mucho la capa de la base de datos para realizar múltiples cambios en la misma, a través de procedimientos almacenados y triggers, entre otras cuestiones porque así descargo mucho trabajo en esta capa que esta en un único servidor. Para la aplicación que estoy construyendo te comento, que he creado un poco de arquitectura ORM yo mismo, sin utilizar aplicaciones como Aurelius,etc, porque es una software muy dedicado a una empresa en concreto que utiliza FireBird como base de datos, y de momento no se contempla otras bases de datos. Me he encontrado creando un ORM de la nada y claro te encuentras con aspectos que antes ni necesitabas ni intuías.

En todo caso, muy agradecido por tu atención.

Un Saludo


La franja horaria es GMT +2. Ahora son las 20:02:24.

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