![]() |
AW: Singleton in Delphi
OK, dann hier mal meine Gedanken zu einem SingletonPattern
die Basisklasse für Delphi 2009 und davor:
Delphi-Quellcode:
die Basisklasse ab Delphi 2010 (die ältere Version geht aber auch noch):
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.
Delphi-Quellcode:
und eine Beispielklasse:
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;
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; |
AW: Singleton in Delphi
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. |
AW: Singleton in Delphi
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:
Du kannst es aber manuell selber machen, indem du TObjekt bei TSingleton abänderst.
TSingleton<Base: class> = class(Base)
... end; Man könnte ja zumindestens eine Codevorlage daraus basteln. |
AW: Singleton in Delphi
Zitat:
|
AW: Singleton in Delphi
Zitat:
du hast quasi dieses
Delphi-Quellcode:
gemacht, aber nicht jenes
TSingleton<T> = class
... class property Instance: T read FInstance; ... end;
Delphi-Quellcode:
.
TSingleton<T> = class<T>
... end; Also du hast eine Klasse in einer anderen Klasse/Record verpackt. (wobei man dort eben auch noch aufpassen muß, daß man dieses gekapselte Objekt nicht extern freigibt) Bei mir und wenn dieser Generic so ginge, würde das Objekt von dem Singleton abgeleitet und hätte dann in sich selber diese Funktionalität aufgenommen. Oder man leitet den Singleton von der gewünschten Klasse ab und baut dieses Verhalten dann nachträglich ein (hierfür muß man aber zusätzlich noch alle Konstruktoren überschreiben/verdecken und mit Konstrukoren besetzen, welche der dem vorhandenen TSingleton.Create entsprechen). |
AW: Singleton in Delphi
Zitat:
Delphi-Quellcode:
gebaut, denn genau das, was den Singleton ausmacht ist, nämlich, dass nur einmal eine Instanz erzeugt wird und verhindert wird, diese freizugeben, ist gegeben.
TSingleton<T> = class<T>
... end; |
AW: Singleton in Delphi
Irgendwie wird in meinem D2010 dein Class-Constructor nicht aufgerufen.
Folglich bleibt die Instanz immer nil und beim Zugriff darauf knallt es dann immer. |
AW: Singleton in Delphi
Zitat:
|
AW: Singleton in Delphi
Erst hatte ich was Eigenes versucht, aber auch mit deinem Beispielcode aus'm Post #1 (mit TStringList statt TFoo) geht's nicht.
|
AW: Singleton in Delphi
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:13 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