Einzelnen Beitrag anzeigen

Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.475 Beiträge
 
Delphi 12 Athens
 
#5

AW: Abgeleitete Klasse eines Singleton Objekts

  Alt 30. Sep 2022, 23:34
Das könnte man auch etwas eleganter mit Generics lösen.

Zunächst ein generischer Singleton (Light):
Delphi-Quellcode:
type
  TSingleton<T:class, constructor> = class
  strict private
  class var
    FInstance: T;
    class destructor DestroyClass;
  private
    class function GetInstance: T; static;
  public
    class property Instance: T read GetInstance;
  end;

class destructor TSingleton<T>.DestroyClass;
begin
  FInstance.Free;
end;

class function TSingleton<T>.GetInstance: T;
begin
  if FInstance = nil then
    FInstance := T.Create;
  result := FInstance;
end;
Dann die zwei Basisklassen, wobei die Description Klasse einen generischen Owner erhält (die TsngColumns habe ich weggelassen):
Delphi-Quellcode:
type
  TsngColumnsOwner = class
  private
    FInitialized: Boolean;
  public
    constructor Create; virtual;
    destructor Destroy; override;
    property Initialized: Boolean read FInitialized write FInitialized;
  end;

type
  TsngColumnDescription<TOwner: TsngColumnsOwner, constructor> = class
  protected
    FsngColumnsOwner: TOwner;
    function GetSngColumnsOwner: TOwner;
  public
    constructor Create; virtual;
    destructor Destroy; override;
    property CD: TOwner read GetSngColumnsOwner;
  end;

{ TsngColumnsOwner }

constructor TsngColumnsOwner.Create;
begin
  inherited Create;
  FInitialized := False;
end;

{ TsngColumnDescription }

destructor TsngColumnDescription<TOwner>.Destroy;
begin
  FsngColumnsOwner.Free;
  inherited;
end;

constructor TsngColumnDescription<TOwner>.Create;
begin
  inherited Create;
  FsngColumnsOwner := TOwner.Create;
end;

function TsngColumnDescription<TOwner>.GetSngColumnsOwner: TOwner;
begin
  Result := FsngColumnsOwner;
end;
Die Ableitungen sehen dann so aus (erspart die overrides):
Delphi-Quellcode:
type
  TkaoPfandColumnDescription = class(TsngColumnsOwner);
  TColKaoPfand = class( TsngColumnDescription<TkaoPfandColumnDescription>);
Und der Zugriff auf den TColKaoPfand-Singleton geht dann so:
Delphi-Quellcode:
begin
  var ColKaoPfand := TSingleton<TColKaoPfand>.Instance;
  if not ColKaoPfand.CD.Initialized then
    ShowMessage(ColKaoPfand.CD.ClassName);
end;
Der Unterschied ist, dass der Singleton nicht mehr an die Basisklasse gebunden ist, sondern eine generische Klasse ist. Diese funktioniert mit allen Klassen, die einen parameterlosen Constructor haben.

Die generische TsngColumnDescription benötigt die Angabe der Owner-Klasse nur bei der Deklaration und nicht mehr beim Create.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat