Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   fichero log (https://www.clubdelphi.com/foros/showthread.php?t=76911)

zampa 04-12-2011 01:00:20

fichero log
 
Hola amigos.

Estoy desarollando una pequeña aplicación en Delphi. Por su puesto, he intentado enforcarlo desde el punto de vista OOP, y claro, tengo un montón de clases, y derivadas.

La aplicación es fundamentalmente matemática: leo ficheros con datos (coordenadas), y ficheros de configuración, y dependiendo del fichero de configuración manipulo las coordenadas de una forma u otra.

Ahora me he dando cuenta de que tengo que crear un especie de protocolo, o log, para que aunque no esté en modo debug, sepa lo que pasa internamente en el programa, o el usuario sepa lo que pasa: que pasos se han dado, cuales han sido los resultados intermedios, cuanto tiempo ha costado calcularlo, ... Asín que me hace falta un fichero log. Para ello crearé la clase LOG y luego un único objeto LOG, y ahí va mi pregunta:

¿Que considerais mejor?
1. crear un objeto log, que sea global a todo, y a lo que todos los objetos tengan acceso, o
2. crear el objeto log, y pasarselo a todos los objetos (que puede resultar algo engorioso y repetitivo).

¿Hay otras opciones?

De momento me vale con una aplicación en línea de comandos. Luego le habrá que crear una interfaz gráfica, pero el fichero log deberá permanecer, y preferiblemente como fichero texto.

¿Que estrategia recomendais para el fichero log?

Casimiro Notevi 04-12-2011 10:51:27

Bienvenido a clubdelphi, ¿ya leiste nuestra guía de estilo?, gracias por tu colaboración.

Para lo que quieres hacer te puede venir bien un simple fichero de texto, haz una búsqueda por los foros de: TextFile
Avisa si no encuentras lo que buscas.

duilioisola 04-12-2011 13:08:05

Yo te recomendaría la segunda opción:

Código Delphi [-]
clase TLog
  Fichero: string
  Lineas: TStrings
  procedure Inicializar(UnFichero: string);  // Asigna el nombre del fichero donde guardar el log y crea Lineas
  procedure NuevaLinea(s: string) // Crea una nueva linea en el log (fecha - hora - s)
  procedure Dump; // Guarda las lineas en el fichero y borra Lineas
end

clase TMatematica1
  ...
  MiLog : Log
  ...
  procedure HacerAglo;
  procedure AsignaLog(Log : TLog)
end

procedure TMatematica1.AsignaLog(Log : TLog)
begin
  MiLog := Log;
end

procedure TMatematica1.HacerAglo;
var
  Resultado : Integer;
begin
  if Assigned(MiLog) then MiLog.NuevaLinea('Matematica1 esta HaciendoAlgo');
  ...
  if Assigned(MiLog) then MiLog.NuevaLinea('Resultado de Matematica1: ' + IntToStr(Resultado));
end

zampa 04-12-2011 17:41:51

Muchas gracias.

Vale, lo que recomiendas es hacer una clase log, y crear en todas las clases que la usen un puntero que apunte a un objeto de esa clase.

¿Existe la posibilidad de crear un objeto log, que sea global a todas las clases, y que no tenga que ser pasado a todos los objetos que hagan uso de él? Lo pienso, como siempre tendré solamente un objeto log...

duilioisola 04-12-2011 18:06:56

Cita:

¿Existe la posibilidad de crear un objeto log, que sea global a todas las clases?
Si existe...
Creas la clase TLog y luego la instacias y la utilizas desde cualquier otro lugar...
El problema: Reutilización!
Si en otro proyecto quieres utilizar alguno de los objetos que habías creado tendrás que crear una clase TLog con el mismo nombre y que quizás no quieras.
También tendrá que estar en el mismo Formulario o DataModule.

He visto que en mi post anterior se repite código. Supongo que esto sería mejor y que puedes agregar a cada una de las clases que tengas:
Código Delphi [-]
clase TMatematica1
  ...
  private
     MiLog : Log
     procedure NuevaLineaLog(s: string)
  ...
  public
    procedure HacerAglo;
    procedure AsignaLog(Log : TLog)
end

procedure TMatematica1.AsignaLog(Log : TLog)
begin
  MiLog := Log;
end

procedure NuevaLineaLog(s: string)
begin
  if Assigned(MiLog) then MiLog.NuevaLinea('Matematica1 esta HaciendoAlgo');
end

procedure TMatematica1.HacerAglo;
var
  Resultado : Integer;
begin
  NuevaLineaLog('Matematica1 esta HaciendoAlgo');
  ...
  NuevaLineaLog('Resultado de Matematica1: ' + IntToStr(Resultado));
end

duilioisola 04-12-2011 18:10:43

De manera global sería más o menos así:
Código Delphi [-]
clase TLog
  Fichero: string
  Lineas: TStrings
  procedure Inicializar(UnFichero: string);  // Asigna el nombre del fichero donde guardar el log y crea Lineas
  procedure NuevaLinea(s: string) // Crea una nueva linea en el log (fecha - hora - s)
  procedure Dump; // Guarda las lineas en el fichero y borra Lineas
end

clase TMatematica1
  ...
  MiLog : Log
  ...
  procedure HacerAglo;
end

procedure TMatematica1.HacerAglo;
var
  Resultado : Integer;
begin
  LogGlobal.NuevaLinea('Matematica1 esta HaciendoAlgo');
  ...
  LogGlobal.NuevaLinea('Resultado de Matematica1: ' + IntToStr(Resultado));
end

var
   LogGlobal : TLog;
begin
  LogGlobal.Inicializar('c:\Log.txt');
  ...
  LogGlobal.Dump;
end.

Neftali [Germán.Estévez] 05-12-2011 10:42:37

Personalmente creo (y así lo hago yo) que es mejor un elemento Global a toda la aplicación. Puede ser una clase o un componente.

Yo mismo tengo publicado uno que utilizo en algunas de mis aplicaciones; El componente TlogDisk, que forma parte de GLib.



El código lo puedes descargar y puedes echarle un vistazo. Cualquier sugerencia para completarlo también será bienvenida.

Lepe 05-12-2011 17:21:15

Yo creo para algo está la parte "initialization" y "finalization" de la unidad. Así, creas y destruyes el log en los lugares adecuados.

Si una unidad hace un uses de la unidad UnitLog, primero se inicializa la unidad UnitLog (creandose la variable Log y estando disponible antes de que se cree la primera ventana que hace uso de él). Al destruirse, se destruye cuando ya nadie hace uso de dicha unidad, por tanto es de nuevo, el lugar adecuado.

En lo personal, tengo Mi log creado en una única .pas como una clase y siempre abro el archivo, guardo el string y cierro el archivo de log. Es algo egoista en el uso del disco duro, pero siempre tendré todos los mensajes de depuración aún cuando haya excepciones anidadas y cosas raras... nunca se queda el archivo de log abierto, con mensajes pendientes ni nada de eso...

Código Delphi [-]

type TlpLog = class(TObject)
...

end;

var log:TlpLog;

implementation

....

initialization 
log := TlpLog.Create;

finalization 
log.free;

Con solo hacer un "uses" de esta unidad, ya puedes usar el log.

zampa 07-12-2011 14:40:19

Muchas gracias por todas las respuestas.

Al final me he decantado por declarar el objeto global, y hacer únicamente uso del uses. Desde cualquier sitio dónde los necesito lo llamo. Como parámetro incluyo self, para poder decir de quien ha venido la llamada, y que padres y abuelos tiene.

Bueno, muchas gracias por la ayuda. Me ha servido de mucho :)


La franja horaria es GMT +2. Ahora son las 21:52:32.

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