![]() |
Singleton in Delphi
Liste der Anhänge anzeigen (Anzahl: 1)
Ein kleines Nebenprodukt was beim Experimentieren in Delphi 2010 entstanden ist.
Ich weiß, Singletons sind böse... 8-) Trotzdem hier mal eine ab Delphi 2010 funktionierene (evtl auch Delphi 2009 oder eher) Unit, die aus einer normalen Klasse ein Singleton macht, wovon weder ein zweites mal eine Instanz erzeugt noch die bestehende Instanz freigegeben werden kann. Hab es bisher im kleinen Stil getestet und dachte, evtl interessiert sich hier der eine oder andere für son krankes Zeug :lol: Die Benutzung ist denkbar einfach, nachfolgend kurz, was so alles funktioniert:
Delphi-Quellcode:
Die Instanz der Klasse wird beim Starten des Programms (ich vermute in Initialization Reihenfolge der Units, genau hab ich es noch nicht getestet) erstellt und beim Beenden (Finalization der Unit Singleton.pas) wieder freigegeben. Der VMT Hack wird vorher schon (Vermutung: finalization der Unit wo der jeweilige Singleton benutzt wird) entfernt.
uses
Singleton; type TFoo = class private FText: string; public property Text: string read FText write FText; end; type TFooSingleton = Singleton<TFoo>; var FooSingleton: Singleton<TFoo>; Foo: TFoo; begin Foo := FooSingleton; TFooSingleton.Instance.Text := 'Hello Foo'; ShowMessage(Foo.Text); end; |
AW: Singleton in Delphi
Entschuldige die Nachfrage, aber: Was kann nun deine Implementation, was eine normale Singleton-Implementation, die mit locker 1/5 der LOCs auskommt, nicht kann? Konnte ich beim Überfliegen jetzt nicht so direkt feststellen.
|
AW: Singleton in Delphi
Hi,
auch von mir eine Nachfrage: Warum sind Singletons deiner Meinung nach böse? Liebe Grüße, Frederic |
AW: Singleton in Delphi
Zitat:
Singletons sind nichts anderes als globale Variablen. Globale Variablen verhindern das isolierte Testen von Klassen und bringen unerwüschte Seiteneffekte. Dieses Youtube Video ist leider nur auf Englisch verfügbar: ![]() aber es zeigt ausführlich, weshalb man Singletons unbedingt vermeiden sollte. |
AW: Singleton in Delphi
Zitat:
Der Vorteil den es bei meiner Implementierung gibt, ist, dass ich die Singleton Eigenschaft von der eigentlichen Klasse trenne. Deshalb ist die Aussage, Singletons seien böse auch eher scherzhaft gemeint, da ich weiß, dass einige diese Meinung vertreten. Das bezieht sich aber eher auf Nebeneffekte, die mit einem Singleton einher kommen können (hohe Kopplung, schwere Testbarkeit). (Dazu ein ![]() |
AW: Singleton in Delphi
Einen IMHO bulletproves Singleton läßt sich über:
Delphi-Quellcode:
erstellen....
type
TSingleton = class sealed private constructor Create; public Prozedure Tuwas; destructor Destroy; override; class function GetInstance : TSingleton; end; implementation var Singleton : TSingleton ; class function TEventDistributor.GetInstance : TSingleton ; begin if Singleton = nil then Singleton := TSingleton .Create; result := Singleton ; end; und eine Aufruf über: TEventDistributor.GetInstance.Tuwas |
AW: Singleton in Delphi
Warum nicht die Variable auch noch mit in die Klasse?
Delphi-Quellcode:
Und den Destructor würde ich noch absichern, damit keiner die Instanz von extern freigeben kann.
type
TSingleton = class sealed private class var Singleton : TSingleton; constructor Create; public procedure Tuwas; destructor Destroy; override; class function GetInstance : TSingleton; end;
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; |
AW: Singleton in Delphi
jep, Du hast mit beidem recht ....
|
AW: Singleton in Delphi
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. |
AW: Singleton in Delphi
Man kann auch den Constructor überschreiben, so daß dort entweder ein Objekt erzeugt oder das bestehende Singleton zurückgegeben wird.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:52 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