Ver Mensaje Individual
  #14  
Antiguo 17-02-2009
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Reputación: 30
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
¡Hola!

Bueno, continuando con la singletonmanía , ahí les va mi propuesta:

Código Delphi [-]
Unit UUnico;

Interface

  Type
    TUnico = Class
      Class Function NewInstance :TObject; Override;
      Procedure FreeInstance; Override;
    End;

  Function Unico :TUnico;  // Función global para acceder a la instancia

Implementation

  Uses
    SysUtils;

  Var
    Instancia :TUnico;  // Variable privada que apuntará a la instancia
    Bloqueado :Boolean;  // Bandera de control

  Class Function TUnico.NewInstance :TObject;
  Begin
    If Bloqueado Then
      Raise Exception.Create ('Intento de crear nuevamente objeto Unico.');

    Result := Inherited NewInstance;
  End;

  Procedure TUnico.FreeInstance;
  Begin
    If Bloqueado Then
      Raise Exception.Create (
        'Intento de destruir prematuramente objeto Unico.');

    Inherited FreeInstance;
  End;

  Function Unico :TUnico;
  Begin
    // a) Creamos la instancia cuando sea requerida por primera vez o...
    If Instancia = Nil Then
    Begin
      Instancia := TUnico.Create;
      Bloqueado := True;
    End;

    Result := Instancia;
  End;

Initialization
  // ...b) Creamos la instancia desde que inicie el programa
  Instancia := TUnico.Create;
  Bloqueado := True;

  // NOTA: Utilice la opción "a" o la opción "b", pero no ambas.

Finalization
  // Destruimos la instancia hasta que finalice el programa
  Bloqueado := False;
  Instancia.Free;

End.

Código Delphi [-]
Uses
  UUnico;

procedure TForm1.Button1Click(Sender: TObject);
Var
  U :TUnico;
begin
  ShowMessage (Unico.ClassName);

  // Imposible
  U := TUnico.Create;

  // Imposible
  Unico.Free;

  // Imposible
  U := Unico;
  U.Destroy;
end;

El problema que veo en el esquema sugerido por Marcelo es que permite nuevas sentencias de instanciación (TSingleton.Create), que darían lugar a re-ejecutar el código del constructor, a pesar de que no se crea una instancia nueva. Si el objeto ya existe, creo que no tendría por qué ser ejecutado el código de su constructor cada vez que alguna parte del programa vaya a usar ese objeto.

La solución con interfaz de Román es efectiva porque consigue que no pueda ser construido el objeto por segunda vez ni destruido prematuramente. El esquema que propuse ahora no es más que otra manera de lograr eso mismo.

Saludos.

Al González.
Responder Con Cita