Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Evitar variables globales.... (https://www.clubdelphi.com/foros/showthread.php?t=74963)

linuxtin 21-07-2011 16:37:57

Evitar variables globales....
 
Holaa!! Como andan!!! La duda que tengo es la siguiente, tengo un form llamado login, en este form lo que hago es identificar y autenticar al usuario, una vez que los datos son correctos guardo por medio de una consulta sql el ID del empleado, la fecha de ingreso, etc.

Hasta ahí todo bien, después lo que hago es guardar en una variable global el ID_Cliente, y hago el form invisible. Esto lo hago porque durante la ejecución del programa uso el ID_Cliente que se logueo para otros usos, como por ejemplo cuando carga algún dato, o modifica guardo el ID_Empleado que lo hizo, ademas de darle los permisos en fin...

No habrá otra manera de hacer esto para evitar la variable global??

Desde ya muchas gracias!!!

oscarac 21-07-2011 16:47:47

yo hago algo similar
pero la variable no la asigno en el form del login sino mas bien en el DataModule

y cuando quiero hacer referencia a la variable hago mas o menos asi

Código Delphi [-]
 
tblloqueseaUsuario.asstring := dmGlobal.g_Usuario;

Casimiro Notevi 21-07-2011 19:41:25

Cita:

Empezado por linuxtin (Mensaje 407013)
No habrá otra manera de hacer esto para evitar la variable global??

Puedes guardarlo en alguna tabla, por ejemplo.

linuxtin 21-07-2011 19:56:41

Cita:

Empezado por linuxtin (Mensaje 407013)
Holaa!! Como andan!!! La duda que tengo es la siguiente, tengo un form llamado login, en este form lo que hago es identificar y autenticar al usuario, una vez que los datos son correctos guardo por medio de una consulta sql el ID del empleado, la fecha de ingreso, etc.

Hasta ahí todo bien, después lo que hago es guardar en una variable global el ID_Cliente, y hago el form invisible. Esto lo hago porque durante la ejecución del programa uso el ID_Cliente que se logueo para otros usos, como por ejemplo cuando carga algún dato, o modifica guardo el ID_Empleado que lo hizo, ademas de darle los permisos en fin...

No habrá otra manera de hacer esto para evitar la variable global??

Desde ya muchas gracias!!!

Muchachos me equivoque donde dice ID_Cliente es ID_Empleado.

Gracias a los dos por responder, oscarac porque un datamodule y no una unidad?

Casimiro el ID_Empleado lo guardo en la tabla del login, pero de todas formas me tengo que quedar con la variable del ID_Empleado hasta que este cierra sesión. Se entiende??

Desde ya muchas gracias!

Casimiro Notevi 21-07-2011 20:15:16

Si te hace falta en todo momento y en cualquier sitio del programa entonces lo mejor es esa variable global :)

Me refería a guardarlo en una tabla para cuando te hiciera falta, para hacer algo así como:
Código SQL [-]
select id_empleado from tbConectado
Así, sin más, una tabla con un sólo registro, el empleado conectado.
Aunque así estás limitando tu programa a monousuario.
Lo dicho, sigue con la variable global, a veces hay que usarlas.

Chris 21-07-2011 21:32:14

Cita:

Empezado por linuxtin (Mensaje 407013)
... después lo que hago es guardar en una variable global el ID_Cliente, y hago el form invisible. Esto lo hago porque durante la ejecución del programa uso el ID_Cliente que se logueo para otros usos, como por ejemplo cuando carga algún dato, o modifica guardo el ID_Empleado que lo hizo, ademas de darle los permisos en fin...

No habrá otra manera de hacer esto para evitar la variable global??

Desde ya muchas gracias!!!

De hecho estás mal implementando la idea de variables globales. En tu caso es lo que necesitarías. Supongo que lo que tú realmente quieres evitar es utilizar la variable del formulario. De hecho es lo mejor, porque así podrías liberar la memoria utilizada por el formulario de inicio una vez que el usuario ha iniciado sesión.

Supongo que tu código debe ser algo cómo esto:
Código Delphi [-]
type
    TFormularioInicio = class(TForm)
    public
        id_empleado: Integer;
    ....
Esto hace que la variable id_empleado dependa de una instancia de TFormularioInicio. Lo que debes hacer para evitar esta dependencia es sacar la mencionada variable de la declaración de TFormularioInicio. Mueve la variable id_empleado a la sección de variables globales mantenidas por la unidad. Por ejemplo:

Código Delphi [-]
unit inicio_sesion

interface
    uses ...
    
type
    TFormularioInicio = class(TForm)
    ....
    end;
    
var
    FormularioInicio: TFormularioInicio
    id_empleado: Integer; // <= nuevo lugar de la variable
                          // (será global y no dependerá de una
                          //  instancia de TFormularioInicio).
                          
implementation
    ....

Espero que esto sea lo que realmente necesitas y que también hallas entendido lo que he querido decir.

Saludos,
Chris

linuxtin 21-07-2011 23:22:18

Gracias Chris! Se entendió lo que explicaste, por lo que veo no queda otra que usar variable global. Es que siempre leí que hay que tener cuidado con estas variables, que no es una buena técnica usar estas variables pero en algunos casos veo que no queda otra opción!!

Saludos y gracias a todos!!

Delphius 22-07-2011 01:56:25

Hola,
linuxtin no es que hay que evitar usarlas. Habrá momentos en que se requiere de un contexto global y en otras ocasiones que es viable el local.

Todo tiene sus pros y contras, y su campo de uso.

Esto del no usar variables globales se ha convertido en un mito... tan arraigado que uno se cree que es peligrosísimo, un terrible pecado. Y luego van los profes promoviendo eso, y luego estos estudiantes al ocupar el lugar de profes, vuelven a vender el mismo pensamiento.

¡Las variables globales no son malas! Lo que es malo es el mal uso (y/o abuso) de ellas... en todo caso la culpa es de quien programa que no lleva los controles adecuados, porque si lo hiciera y fuera ordenado no hay problema alguno de usarlas. Pero claro es más fácil decir ¡no las uses!

Es justo el mismo problema y estigma que carga el concepto del Acoplamiento. Muchos lo han victimado y culpado de todos los mil y un males... El acoplamiento es inevitable, siempre habrá algo (como siempre habrá alguna variable global, sino me crees busca por Application ;) ). Lo que hay que hacer, en todo caso, es controlarlo y equilibrarlo junto al concepto de Cohesión... en las variables globales es lo mismo: controlar y equilibrar su uso.

Saludos,

Neftali [Germán.Estévez] 22-07-2011 09:45:10

Pues como ya te han comentado NO SIEMPRE HAY QUE EVITAR LAS VARIABLES GLOBALES. Cuando son necesarias hay que usarlas (como en este caso). Con la puntualización que ha hecho Chris, de que realmene sea global y no ligada al formulario

En mi caso, para esto (y algunas cosas similares) me creo una clase de configuración que almacena todos esos datos genéricos (que deben ser accesibles por toda la aplicación en cualquier momento). Pero sigue siendo lo mismo.

Tengo una instancia de la clase TGConfig que es global y dentro de esa clase TGConfig una serie de datos "globales".

Casimiro Notevi 22-07-2011 10:55:46

Yo uso una nomenclatura "propia" derivada de la notación húngara de Charles Simonyi, por ejemplo, para las constantes uso este tipo de nomenclatura:

Código Delphi [-]
const
  _CONFIGINI_  : string = 'config.ini';
  _RUTA_BD_    : string = '\BasesDatos\';
Y para las variables globales, similar, pero en minúsculas:

Código Delphi [-]
public
  _iCodEmpresa_   : integer;
  _dFechaTrabajo_ : TDateTime;


De esa manera siempre tengo controlado cada cosa.

linuxtin 22-07-2011 15:20:45

Gracias a todos por sus opiniones!!

Delphius toco el tema de acoplamiento y cohesión,como hacen ustedes para lograr una alta cohesión y un bajo acoplamiento en delphi? Como puedo guiarme para saber cuando tengo que descomponer una unidad en varias?

Saludos!

Delphius 22-07-2011 20:00:21

Cita:

Empezado por Casimiro Notevi (Mensaje 407142)
Yo uso una nomenclatura "propia" derivada de la notación húngara de Charles Simonyi, por ejemplo, para las constantes uso este tipo de nomenclatura:

Código Delphi [-]const _CONFIGINI_ : string = 'config.ini'; _RUTA_BD_ : string = '\BasesDatos\';

Y para las variables globales, similar, pero en minúsculas:

Código Delphi [-]public _iCodEmpresa_ : integer; _dFechaTrabajo_ : TDateTime;



De esa manera siempre tengo controlado cada cosa.

¿A cuál publicación de Simonyi te refieres amigo? ¿A la original, o la que terminó publicando Microsoft? :rolleyes: Esto te lo pregunto justamente por lo que he leído en este artículo.
Una mala interpretación de las palabras de Charles terminó en lo que se conoció como Notación Húngara que promovió Microsoft. ;)

Cita:

Empezado por linuxtin (Mensaje 407152)
Gracias a todos por sus opiniones!!

Delphius toco el tema de acoplamiento y cohesión,como hacen ustedes para lograr una alta cohesión y un bajo acoplamiento en delphi? Como puedo guiarme para saber cuando tengo que descomponer una unidad en varias?

Saludos!

No hay una receta mágica para eso. Es cosa de análisis, y hay tantas maneras de evaluarlo como personas. Cada quien tendrá su forma de verlo, y sabes ¡puede que todos tengan razón! ;)

Mientras te sientas cómodo con tu diseño, no deberías preocuparte. Es en cuanto dudas en donde debes preocuparte.
Si tu estás siguiendo un proceso basado o apoyado en métricas quizá podrías proponer alguna que represente cualitivamente un aproximado de cuanto acomplamiento y cohesión tienes... si logras tener por decirlo de algún modo 0,5 y 0,5 ¡estás hecho!

Dale una revisada al libro Ingeniería de Software: un enfoque práctico de Robert Pressman. De allí te puedes hacer una idea.

También hay que considerar el hecho de al considerar el paradigma OO ya tenemos dos tipos de Acoplamiento: el acoplamiento entre los módulos o unidades, ¡y el acomplamiento mismo entre las clases!

Saludos,

Casimiro Notevi 22-07-2011 21:07:07

Cita:

Empezado por Delphius (Mensaje 407193)
¿A cuál publicación de Simonyi te refieres amigo? ¿A la original, o la que terminó publicando Microsoft? :rolleyes: Esto te lo pregunto justamente por lo que he leído en este artículo.
Una mala interpretación de las palabras de Charles terminó en lo que se conoció como Notación Húngara que promovió Microsoft. ;)

A la original, ten en cuenta que yo empecé con estas cosas en 1985 :eek:, no existía windows y casi, casi... ni microsoft :D, y básicamente Simonyi lo usaba para el lenguaje C, que al contrario que "nuestro" Delphi, podías (y puedes) asignar valores de un tipo a variables de cualquier otro tipo y, como es natural, te saltaban unos errores tremendos.
Así que yo también usé esa técnica ya por aquella época, por ejemplo:
Código Delphi [-]
var
  iCodInforme,
  iIndice     : integer;
  fPorcentaje : float;
  aiParametros: array of integer;
  dFecha      : TDateTime;
  cCuenta,
  cPrefijo    : string; 
  bAceptado   : boolean;
Como ves, todavía usa el prefijo 'c' para string porque en lenguaje C los strings no existen, son cadenas de 'c'aracteres, y sigo nombrándolos así.
Uso los prefijos para todo, así es muy difícil equivocarse, por ejemplo:

Código Delphi [-]
iDato := 1;
cDato := 'Hola';
fCantidad := 2.36;
aiValor[iX] := 3;      // array de integer

Es casi imposible equivocarse porque estoy viendo el tipo de dato que espera la variable.

Todos los componentes y controles, igual, con 2 caracteres:

Código Delphi [-]
lbAviso : TLabel;
edCliente : TEdit;
cbOpciones : TComboBox;
dtFecha : TDateTimePicker;

Sin embargo para los controles de datos, uso las mayúsculas:

Código Delphi [-]
DScuentas : TDataSource;
TRprincipal : TTransaction;
DBprincipal : TDataBase;

Por eso digo que uso una versión "propia", porque con los años he ido amoldándolo a mis necesidades.

Además de evitar errores también facilita la lectura de código fuente, lo hace más intuitivo a la hora de depurar, por ejemplo.

Hay varias cosas que dice el texto que has enlazado y que estoy de acuerdo:

Cita:

El Húngaro para Aplicaciones fue algo extremadamente valioso, especialmente en los días de programación C donde el compilador no te daba una muy útil verificación de tipos.
Como he dicho antes, en aquella época era esencial.

Cita:

Pero hay aun un tremendo valor en el Húngaro para Aplicaciones, en que incrementa el factor de colocación del código, hace que sea fácil de leer, escribir, depurar, y mantener, y, más importante aún, hace que el código defectuoso se vea defectuoso.
Pues eso, lo que he dicho antes, totalmente de acuerdo.

Cita:

Antes de continuar, hay una cosa más que prometí hacer, la cual es meterme con las excepciones una vez más. La última vez que lo hice me metí en un montón de problemas. En una frase algo fuera de tono en la pagina de “Joel on Software”, escribí que no me gustan las excepciones porque ellas son, verdaderamente, un goto invisible, lo cual, razoné, es aun peor que un goto que puedes ver. Claro está decir que millones de personas se abalanzaron por mi garganta. La única persona en el mundo que salto en mi defensa fue, claro está, Raymond Chen, quien es, de paso, el mejor programador del mundo, así que tiene algo que decir, no?
Tiene toda la razón, muchas veces las excepciones son 'gotos' a no se sabe dónde :D

roman 25-07-2011 17:16:57

Cita:

Empezado por Neftali (Mensaje 407136)
Pues como ya te han comentado NO SIEMPRE HAY QUE EVITAR LAS VARIABLES GLOBALES. Cuando son necesarias hay que usarlas (como en este caso). Con la puntualización que ha hecho Chris, de que realmene sea global y no ligada al formulario

En mi caso, para esto (y algunas cosas similares) me creo una clase de configuración que almacena todos esos datos genéricos (que deben ser accesibles por toda la aplicación en cualquier momento). Pero sigue siendo lo mismo.

Tengo una instancia de la clase TGConfig que es global y dentro de esa clase TGConfig una serie de datos "globales".

No he leido a detalle todo el hilo pero me quedo con este mensaje.

De entrada no creo que sea "flojera" de los profesores el recomendar no usar variables globales, ni tampoco creo que sea un mito. Las variables globales conviene evitarlas porque hay poco control sobre ellas. Claro que si somos muy ordenados, no debería preocuparnos tanto, pero si todo fuera cuestión de orden para programar, ni siquiera necesitaríamos OOP.

¿Por qué escojo el mensaje de Neftalí para contestar en este hilo? Porque si bien parece estar de acuerdo en el uso de variables globales según qué circunstancias; en la parte subsecuente de su mensaje contradice esto indicando que reune estas variables globales en una clase TGConfig, cosa muy, pero muy distinta a tener una variable global suelta por ahí.

Yo hago algo como lo que menciona oscarac, y que todos parecen haber omitido, y que al, final es similar a lo que hace Neftali. Tengo un datamodule donde abro conexiones, leo valores de incio de algún archivo de configuración e incializo variables "globales", que, en realidad, son propiedades de ese datamodule.

// Saludos

Casimiro Notevi 25-07-2011 18:19:34

Cita:

Empezado por roman (Mensaje 407332)
Yo hago algo como lo que menciona oscarac, y que todos parecen haber omitido, y que al, final es similar a lo que hace Neftali. Tengo un datamodule donde abro conexiones, leo valores de incio de algún archivo de configuración e incializo variables "globales", que, en realidad, son propiedades de ese datamodule.
// Saludos

Normalmente lo pongo en una unit "normal" habilitada para estas cosas, ¿hay algún motivo especial para usar un datamodule?

roman 25-07-2011 18:49:38

No, ninguno, salvo el hecho de tenerla en una clase y no como variable global suelta. Lo del datamodule es sólo para aprovechar que ya tengo uno para menesteres de tipo inicialización, de hecho es donde pongo el componente de conexión. Aunque si son valores cuya naturaleza no tenga nada que ver con la base de datos, tal datamodule no sería la mejor opción y mejor lo del TGConfif de Germán.

// Saludos

marcoszorrilla 25-07-2011 19:52:26

Yo uso las dos cosas, una Unidad que llamo Global y allí coloco todas las variables que voy a utilizar en toda la aplicación "por encima de las unidades" y el resto procuro crearlas para que solamente vivan durante el ámbito de su aplicación y van en DataModulos...

Un Saludo.

Casimiro Notevi 25-07-2011 20:08:53

Casi todos tenemos costumbres más o menos parecidas :)

marcoszorrilla 25-07-2011 21:09:58

Sin embargo creo que es bueno intercambiar ideas, porque yo reconozco que antes colocaba todo en la Unidad "Menu", basándome en que esa unidad siempre estaba cargada en memoria, sin embargo JMR me hizo caer en la cuenta que eso era una aberración y un insulto a la inteligencia del compilador y desde entonces quité variables del menú y las lleve a Global que por cierto no tiene porque llamarse global.

Un Saludo.

Casimiro Notevi 25-07-2011 23:38:14

Cita:

Empezado por marcoszorrilla (Mensaje 407368)
Sin embargo creo que es bueno intercambiar ideas

Por supuesto que sí.

Casimiro Notevi 26-07-2011 00:23:29

Por cierto, ¿quién es JMR?

roman 26-07-2011 16:32:22

¿No es de esos foreros míticos que por alguna razón que se pierde en la oscuridad del pasado salió del Club?

maeyanes 26-07-2011 18:47:48

Yo recuerdo a JMR de las listas de discusión, cuando esto se manejaba por listas de distribución por email.


Saludos...

marcoszorrilla 26-07-2011 22:25:42

JMR. José Manuel Rodriguez es el autor de las famosas "Trivial", también fue moderador del Club Delphi, fue una pena que se perdiera su concurso en este sitio, pero así son las cosas, hace un tiempo vi que estaba en la lista de FireBird, pero hace tiempo que no he vuelto a saber de él.

Un Saludo.

Casimiro Notevi 26-07-2011 23:49:06

¿Y eso de las variables globales era un documento que escribió o fue algún post en algún foro?, por echarle un vistazo.

marcoszorrilla 27-07-2011 06:52:52

Creo recordar que era un hilo normal en el que por algún motivo salio el tema de las variables y yo dije que las colocaba en el Menú.

Un Saludo.

Paoti 28-07-2011 19:04:27

Vairable Gloables como Variables Estaticas.
 
¡Hola Dudes!

Como ven este acercamiento.

Creando, por así decirlo una propiedad estatica de una clase, y asignarle su valor, que estará visible en todas las unidades (y por ende Forms) donde se requiera.

Espero el cógido sea más legible que mi explicación:


la unidad donde se almacenarán las propiedades globales, por así decirlo
Código Delphi [-]
unit uGlobales;

interface

type
TGlobales = class
private
    // procediminto y función para leer la varables
    // se antepone Class, para indicar que son métodos de clase y on de objeto
    class function GetUsuario : string;
    class procedure SetUsuario(const Value: string);
protected

public
  // Es una propiedad de clase y no de objeto, debido a que usa metodos de clase
  property Usuario : string read GetUsuario write SetUsuario;

published
  { published declarations }
end;

implementation

var
    FUsuario : string;


class function TGlobales.GetUsuario: string;
begin
      Result := FUsuario;
end;

class procedure TGlobales.SetUsuario(const Value: string);
begin
  FUsuario := Value;
end;

end.


Ahora, cuando quieras acceder al valor de la propiedad, o en su defecto asigarle un valor solo tienes que hacer lo sigiuente.

Código Delphi [-]
implementation

uses
  uGlobales;

......

// desde un formulario 2
procedure TForm2.btn1Click(Sender: TObject);
var
  myGlobal : TGlobales;
begin
  Caption := myGlobal.Usuario;
end;

......

// desde un formulario 1
procedure TForm1.btn1Click(Sender: TObject);
var
  myGlobal : TGlobales;
begin
myGlobal.Usuario := 'Paoti';
end;

Dudas, comentarios.

Estará bien esta forma de realizarlo, digo, no lo he puesto en practica en un ambiente de producción.


Gracias.

roman 28-07-2011 19:54:04

A mi me parece muy bien. Esta es una forma de implmentar propiedades estáticas (simuladas) en una clase de Delphi. Creo que las versiones recientes ya admiten este tipo de propiedades.

// Saludos

andres1569 28-07-2011 20:13:05

Interesante técnica :), sin necesidad de crear ni destruir ningún objeto, che !

Neftali [Germán.Estévez] 29-07-2011 15:42:59

Cita:

Empezado por Paoti (Mensaje 407751)
Estará bien esta forma de realizarlo, digo, no lo he puesto en practica en un ambiente de producción.

Yo no acabo de verle la lógica. Usas una clase Global para acceder a una variable, que en lugar de estar dentro de la clase está fuera.

(1) No le veo ventajas (seguramente es que yo no las veo), pero las hay, entre lo que has puesto tú y esto:

Código Delphi [-]
TGlobales = class private
    FUsuario : string;   <<<<====

     // procediminto y función para leer la varables    
    // se antepone Class, para indicar que son métodos de clase y on de objeto     
    class function GetUsuario : string;     
    class procedure SetUsuario(const Value: string); 
  protected 
  public   
   // Es una propiedad de clase y no de objeto, debido a que usa metodos de clase   
   property Usuario : string read GetUsuario write SetUsuario; 
  published 
end;

(2) Lo segundo que no veo es qué ventajas tiene en este caso usar la clase, respecto a esto:

Código Delphi [-]
unit uGlobales; 
interface 
 var Usuario : string;
implementation 
end.

Y cuando la uses poner

Código Delphi [-]
Caption := uGlobales.Usuario;
...
uGlobales.Usuario := 'pepe';

roman 29-07-2011 17:00:26

A ver si aclaramos un poco:

Una forma de manejar variables de ámbito global sin ser propiamente globales, es encapsularlas en una clase como propiedades estáticas, esto es, como propiedades que no dependen de ningua instancia particular y que, por tanto, pueden usarse sin tener que crear un objeto de la clase.

El punto es que hasta delphi 2010, creo, no había propiedades estáticas -como sí las hay en otros lenguajes. Entonces, para simularlas, se hacía lo que propone Paoti. La variable a la que se accede desde la clase está restringida al ámbito privado de la unidad en la que se declara y, por tanto y es lo importante, no es accesible directamente desde fuera, lo cual, proporciona un cierto grado de control sobre dicha variable. Cosa que no ocurre si simplemente se usa una variable declarada en la sección interface. La variable queda "expuesta" a todo mundo.

Si tal variable se pone "dentro" de la clase, entonces no sería posible usarla sin instanciar un objeto de la clase. Dicho de otra forma, ya no sería una propiedad estática de la clase.

// Saludos

Paoti 29-07-2011 17:13:22

El (1) no funciona, como variable privada, debe ser de la forma como está la clase expuesta por mi anteriormente.

el (2) es otra forma, usando propiedades estáticas simuladas.

Ahora, el ejemplo anterior, del post, es cómo usar otro tipo de Variables Globales, sí no quieres usar la forma tradicional.

Neftali [Germán.Estévez] 29-07-2011 17:22:27

Cita:

Empezado por Paoti (Mensaje 407894)
El (1) no funciona, como variable privada, debe ser de la forma como está la clase expuesta por mi anteriormente.

Correcto.
En ese caso hay que definir una variable global del tipo TGlobales, como comenté antes.

De todas formas, sigo viéndolo "raro".

Chris 29-07-2011 17:26:06

Interesante pauti.

Pero no entiendo el por qué de este código:
Código Delphi [-]
// desde un formulario 2
procedure TForm2.btn1Click(Sender: TObject);
var
  myGlobal : TGlobales;
begin
  Caption := myGlobal.Usuario;
end;

......

// desde un formulario 1
procedure TForm1.btn1Click(Sender: TObject);
var
  myGlobal : TGlobales;
begin
myGlobal.Usuario := 'Paoti';
end;

Cuando simplemente se podría hacer así, según una clase de muestra que he escrito:

Código Delphi [-]
    TGlobalVars = class
        private
            class var FVar1: String;
        public
            class property Var1: String read FVar1 write FVar1;
            // o simplemente:
            class var Var2: String;
    end;

// -------------------------------------------------------//
implementation

procedure TForm2.Button1Click(Sender: TObject);
begin
    TGlobalVars.Var1 := Edit1.Text;
end;

procedure TForm2.Button2Click(Sender: TObject);
begin
    ShowMessage(TGlobalVars.Var1);
end;

roman 29-07-2011 17:32:10

Es que no hay que definir ninguna variable del tipo TGlobales. Simplemente se hace:

Código Delphi [-]
TGlobales.Usuario := 'roman';

Edito:

¡Ah! Veo que Chris ya lo mencionó :)

// Saludos

roman 29-07-2011 17:35:50

Sólo añadir que, con esta técnica, dado que el acceso es vía métodos de una clase, se puede tener un mejor control, validación, etc. Incluso pueden implementarse variables "globales" de sólo lectura, por ejemplo.

// Saludos

Paoti 29-07-2011 17:59:30

¡Hola compañeros!

Me gusta tu idea roman, para evitar usar ahora sí, variables globales


Por ejemplo, una idea sería la siguiente:

Código Delphi [-]

TGlobales.CadenaConexion := 'lcoalhost:baseDatos';
TGlobales.Inicializa('usario', 'pAssW0rd');
TieneAcceso := TGLobales.Activo;
Perfil := TGloables.Perfil;
ultimoAcceso := TGlobales.FEchaUltAcceso


el método Inicializa(), incializa los valores de las propiedades de clase, que serán Globales, y de solo lectura. en base a los datos de la base de datos. y están disponibles en todos lados donde se haga referencia la unidad.

Neftali [Germán.Estévez] 29-07-2011 18:16:56

Yo personalmente hubiera hecho algo así (en realidad es lo que hago).

Sigues manteniendo las propiedades de lectura/escritura de las diferentes variables (ya que eso te lo da la clase), y colocas las variables "dentro" de la clase en lugar de fuera.

Mantienes una variable Global del tipo TGlobales, pero es que de la otra forma también mantienes en memoria todas las variables necesarias. No le veo diferencia en eso.

Código Delphi [-]
unit Globales;

interface

type
  TGlobales = class
  private
    FUsuario : string;
    FCadenaConexion: string;
    FPassWord: string;

    // procediminto y función para leer la varables
    // se antepone Class, para indicar que son métodos de clase y on de objeto
    function GetUsuario : string;
    procedure SetUsuario(const Value: string);
    function GetPassWord: string;
  protected

  public
    // Es una propiedad de clase y no de objeto, debido a que usa metodos de clase
    property Usuario : string read GetUsuario;
    property Password: string read FPassWord;
    property CadenaConexion:string read FCadenaConexion write FCadenaConexion;

    procedure Inicializa(Us,psw:String);
  published
  { published declarations }
  end;

var
  uGlobales:TGlobales;

implementation

uses
  SysUtils;


function TGlobales.GetUsuario: string;
begin
  Result := FUsuario;
end;

procedure TGlobales.Inicializa(Us, psw: String);
begin
  FUsuario := us;
  FPassWord := psw;
end;

procedure TGlobales.SetUsuario(const Value: string);
begin
  FUsuario := Value;
end;

Initialization
  uGlobales := TGlobales.Create();

Finalization
  FreeAndNil(uGlobales)

end.

roman 29-07-2011 18:41:58

La diferencia es que en tu caso debes crear un objeto de esa clase siendo que los datos a los que accedes no dependen realmente de un objeto en particular sino de la clase en sí.

Idealmente se tendría algo así:

Código Delphi [-]
type
  TGlobal = class
  private
    class var FUsuario: String; // <--- Esto no es posible
    class function GetUsuario: String;

  public
    property Usuario: String read GetUsuario;
    class procedure Inicializa;
  end;

implementation

class function TGlobal.GetUsuario: String;
begin
  Result := FUsuario;
end;

class procedure TGlobal.Inicializa;
begin
{
  Aquí se leen los valores de un archivo INI o de la base de datos, etc.

  Este método podría llamarse, por ejemplo, en la inicialización de la unidad.
}
end;

Y, entonces, para usar esos datos lo haces directamente de la clase:

Código Delphi [-]
Caption := TGlobal.Usuario;

Pero, como delphi no permitía las variables de clase, es que se simulan haciendo lo que dice Paoti.

Desde luego que la clase, tal como la usas tú, instanciando un objeto, tampoco es que esté mal. Al final de cuentas cumple con el objetivo de evitar el uso de variables globales.

// Saludos

maeyanes 29-07-2011 18:50:17

Hola...

Y usando el ejemplo de roman en Delphi 2010 y posteriores:

Código Delphi [-]
TGlobal = class
  // ...
public
  class constructor Create; // constructor de clase
end;

implementation

class constructor TGlobal.Create;
begin
  {
  Aquí se leen los valores de un archivo INI o de la base de datos, etc.

  Este constructor se llama automáticamente la primera vez que se quiere usar esta clase.
  }
end;


Saludos...


La franja horaria es GMT +2. Ahora son las 16:19: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