AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Projekte Singleton in Delphi
Thema durchsuchen
Ansicht
Themen-Optionen

Singleton in Delphi

Ein Thema von Stevie · begonnen am 20. Sep 2010 · letzter Beitrag vom 21. Sep 2010
Antwort Antwort
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.340 Beiträge
 
Delphi 12 Athens
 
#1

AW: Singleton in Delphi

  Alt 21. Sep 2010, 10:58
Warum nicht die Variable auch noch mit in die Klasse?
Delphi-Quellcode:
type
  TSingleton = class sealed
  private
    class var Singleton : TSingleton;
    constructor Create;
  public
    procedure Tuwas;
    destructor Destroy; override;
    class function GetInstance : TSingleton;
  end;
Und den Destructor würde ich noch absichern, damit keiner die Instanz von extern freigeben kann.


Delphi-Quellcode:
TSingleton = class sealed
private
  class var Singleton : TSingleton;
  class var AllowFree : Boolean;
  constructor Create;
public
  procedure Tuwas;
  destructor Destroy; override;
  procedure FreeInstance; override;
  class function GetInstance : TSingleton;
end;

class function TSingleton.GetInstance: TSingleton;
var
  S: TSingleton;
begin
  if not Assigned(Singleton) then
  begin
    S := TSingleton.Create;
    if Assigned(InterlockedCompareExchangePointer(Pointer(Singleton), Pointer(S), nil)) then
      S.Free;
  end;
  Result := Singleton;
end;

procedure TSingleton.FreeInstance;
begin
  if AllowFree then
    inherited FreeInstance;
end;

finalization
  TSingleton.AllowFree := True;
  TSingleton.Singleton.Free;
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (21. Sep 2010 um 11:08 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#2

AW: Singleton in Delphi

  Alt 21. Sep 2010, 11:02
jep, Du hast mit beidem recht ....
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.045 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#3

AW: Singleton in Delphi

  Alt 21. Sep 2010, 11:27
Beides schön... aber damit ist "in Stein gemeißelt", dass dies ein Singleton ist. Ich muss überall TSingleton.GetInstance machen und habe deshalb das Problem der hohen Abhängigkeit. Brauche ich eine andere Klasse, die ein Singleton sein soll, muss ich sie von der TSingleton Klasse ableiten (Nachtrag: geht eh nicht, da sealed) oder die gleiche Funktionalität dort einbauen.

Mein Konzept hatte zum Ziel jede beliebige Klasse (theoretisch) in ein Singleton zu verwandelt, indem man das Instanzieren und Freigeben von außen vermeidet. Jemand kann eine ganz normale Klasse schreiben und jemand anders benutzt sie bei sich im Code als Singleton. Entscheidet er sich, ich brauch doch mal 2 oder mehr Instanzen davon nehm ich das Singleton<...> weg und bin glücklich. Außerdem kann ich die Klasse für Unittests einfach ausmocken und muss mich nicht mit den überall fest verschraubten Abhängigkeiten rumärgern.

Eventuell ist mein Ansatz nicht mehr das, was ursprünglich als Singleton verstanden wird, sondern eher ein "OnlyOneInstance"-Wrapper.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.340 Beiträge
 
Delphi 12 Athens
 
#4

AW: Singleton in Delphi

  Alt 21. Sep 2010, 11:49
Man kann auch den Constructor überschreiben, so daß dort entweder ein Objekt erzeugt oder das bestehende Singleton zurückgegeben wird.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.340 Beiträge
 
Delphi 12 Athens
 
#5

AW: Singleton in Delphi

  Alt 21. Sep 2010, 12:24
OK, dann hier mal meine Gedanken zu einem SingletonPattern

die Basisklasse für Delphi 2009 und davor:
Delphi-Quellcode:
type
  TSingleton = class(TObject)
  private
    fIsInitialized: Boolean;
    fAllowFree:     Boolean;
    fIsSingelton:   Boolean;
    class var fSingleton: TSingleton;
    class procedure DoFree;
  protected
    property isInitialized: Boolean read fIsInitialized;  // to see whether the constructor must be executed (in contructors)
    property AllowFree:     Boolean read fAllowFree;      // to detect whether the object is released (in destructors)
    property isSingelton:   Boolean read fIsSingelton;    // note: not yet available in constructor
  public
    class function NewInstance: TObject; override;
    procedure AfterConstruction; override;
    procedure BeforeDestruction; override;
    procedure FreeInstance; override;
  end;

class procedure TSingleton.DoFree;
begin
  if Assigned(fSingleton) then
    fSingleton.fAllowFree := True;
  fSingleton.Free;
end;

class function TSingleton.NewInstance: TObject;
begin
  if Assigned(fSingleton) then
    Result := fSingleton
  else
    Result := inherited;
end;

procedure TSingleton.AfterConstruction;
begin
  inherited;
  fIsSingelton := not Assigned(InterlockedCompareExchangePointer(Pointer(fSingleton), Pointer(Self), nil));
  fIsInitialized := True;
  if not fIsSingelton then fAllowFree := True;
end;

procedure TSingleton.BeforeDestruction;
begin
  if fAllowFree then
    inherited;
end;

procedure TSingleton.FreeInstance;
begin
  if fAllowFree then
    inherited;
end;

class destructor TSingleton.DestroyClass;
begin
  if Assigned(fSingleton) then
    fSingleton.fAllowFree := True;
  fSingleton.Free;
end;

initialization

finalization
  TSingleton.DoFree;

end.
die Basisklasse ab Delphi 2010 (die ältere Version geht aber auch noch):
Delphi-Quellcode:
type
  TSingleton = class(TObject)
  private
    fIsInitialized: Boolean;
    fAllowFree:     Boolean;
    fIsSingelton:   Boolean;
    class var fSingleton: TSingleton;
  protected
    property isInitialized: Boolean read fIsInitialized;  // to see whether the constructor must be executed (in contructors)
    property AllowFree:     Boolean read fAllowFree;      // to detect whether the object is released (in destructors)
    property isSingelton:   Boolean read fIsSingelton;    // note: not yet available in constructor
  public
    class function NewInstance: TObject; override;
    procedure AfterConstruction; override;
    procedure BeforeDestruction; override;
    procedure FreeInstance; override;
    class destructor DestroyClass;
  end;

class function TSingleton.NewInstance: TObject;
begin
  if Assigned(fSingleton) then
    Result := fSingleton
  else
    Result := inherited;
end;

procedure TSingleton.AfterConstruction;
begin
  inherited;
  fIsSingelton := not Assigned(InterlockedCompareExchangePointer(Pointer(fSingleton), Pointer(Self), nil));
  fIsInitialized := True;
  if not fIsSingelton then fAllowFree := True;
end;

procedure TSingleton.BeforeDestruction;
begin
  if fAllowFree then
    inherited;
end;

procedure TSingleton.FreeInstance;
begin
  if fAllowFree then
    inherited;
end;

class destructor TSingleton.DestroyClass;
begin
  if Assigned(fSingleton) then
    fSingleton.fAllowFree := True;
  fSingleton.Free;
end;
und eine Beispielklasse:
Delphi-Quellcode:
type
  TMyClass = class(TSingleton)
    Value: String;
    constructor Create;
    destructor Destroy; override;
  end;

constructor TMyClass.Create;
begin
  if not isInitialized then
  begin
    inherited;
    ////////////////////

    ShowMessage('Ich wurde erstellt');

    ////////////////////
  end;
end;

destructor TMyClass.Destroy;
begin
  if AllowFree then
  begin
    ////////////////////

    //ShowMessage('ich werde jetzt freigegeben');
    // wird nicht mehr angezeigt, nachdem die VCL beendet wurde
    MessageBox(0, 'ich werde jetzt freigegeben', '', 0);

    ////////////////////
    inherited;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  S: TMyClass;
begin
  S := TMyClass.Create;
  S.Value := 'test';
  S.Free;

  S := TMyClass.Create;
  ShowMessage('mein Wert ist: ' + S.Value);
end;
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (21. Sep 2010 um 12:44 Uhr)
  Mit Zitat antworten Zitat
Alt 21. Sep 2010, 12:29     Erstellt von himitsu
Dieser Beitrag wurde von fkerber gelöscht. - Grund: Doppelposting
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.045 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#7

AW: Singleton in Delphi

  Alt 21. Sep 2010, 12:57
Wie schon erwähnt, immernoch das gleiche Problem, du musst eine Klasse, die du als Singleton benutzen willst, von TSingleton ableiten -> Abhängigkeit.
Du kannst keine beliebige (wie schon erwähnt, in Theorie, habs noch nicht mit mehr als TFoo und TBar getestet) Klassen in Singletons umwandeln, ich schon.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.340 Beiträge
 
Delphi 12 Athens
 
#8

AW: Singleton in Delphi

  Alt 21. Sep 2010, 13:04
Joar, das Singleton muß hier quasi an der Spitze stehen.
Leider bieten die Generics es nicht an, daß man damit die Basisklasse setzen kann.
Delphi-Quellcode:
TSingleton<Base: class> = class(Base)
  ...
end;
Du kannst es aber manuell selber machen, indem du TObjekt bei TSingleton abänderst.
Man könnte ja zumindestens eine Codevorlage daraus basteln.
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:42 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz