![]() |
Singletons vererben
Hallo,
ich habe eine "Basis-Singleton"-Klasse erstellt und möchte nun erweiterte Klassen entwickeln, welche das Basis-Verhalten ebenfalls besitzen. Kann ich irgendwie die Singleton-Eigenschaft nur in der Basis-Klasse kapseln und in den abgeleiteten Klassen ausschließlich die Funktionalität implementieren? Ich denke, dass das ohne weiteres nicht gehen wird, da ich ja nur eine Instanz der Singleton-Klasse habe und für meine abgeleiteten Klassen jeweils eine neue Instanz bräuchte. Aber evtl. hat ja jemand dafür einen Workaround gefunden? :-) Wenn es nicht gehen sollte, werde ich in der Basisklasse halt die Singleton-Zugriffsmethoden via abstrakter Class-Funktion vorsehen und in den Unterklassen (ca 5) implementieren... Viele Grüße, Dominik |
Re: Singletons vererben
![]() ![]() ![]() Außerdem bastelt jbg ![]() Aber eine ganz andere Sache: Wie willst du bei 5 verschiedenen Singleton-Nachfahren jeweils eine Instanz ermöglichen? Du bräuchtest dafür doch 5 Variablen, die über die Lebenszeit der Anwendung zugreifbar bleiben. Gibt es auch eine Möglichkeit, in Delphi statische Klassenmember zu deklarieren? Wenn nein, müsstest du doch eh deine Unit anpassen um 5 globale Variablen zur Verfügung zu stellen, die die Instanzen beinhalten. |
Re: Singletons vererben
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
Naja - ich habe jetzt auf jeden Fall für alle Klassen eine eigene Singleton-Implementation vorgesehen. Damit habe ich dann weniger Probleme. Aber dazu hätte ich auch noch eine Frage: Wenn ich meine Oberklasse so aussieht:
Delphi-Quellcode:
Wie kann ich dann diese Instanz-Funktion korrekt zu folgendem ableiten:
TServiceController = class
public class function Instance: TServiceController; virtual; abstract; end;
Delphi-Quellcode:
So bekomme ich eine Compilerwarnmeldung. Wenn ich die Funktion overriden möchte, erhalte ich den Fehler, dass die Typen nicht zueinander kompatibel sind. Nun möchte ich aber auch nicht nur TServiceController zurückliefern, da ich dann immer casten muss... Wie mache ich das also? TLoginServiceController = class(TServiceController ) public procedure Login; class function Instance: TLoginServiceController; end; Viele Grüße, Dominik |
Re: Singletons vererben
Zitat:
Meine persönliche Einschätzung, auch in Bezug auf die Einleitung des Artikels, des Dingens ist, daß es eher eine Spielerei ist. Er ist Delphi-Fanatiker und hatte keinen Bock mehr, von C++lern ausgelacht zu werden, und deswegen hat er sich so einen Code zusammengeschustert. Wahrscheinlich ist er auch einer derjenigen, die immer behaupten, Delphi sei soooo cool, weil der Code viel übersichtlicher und lesbarer ist als der von C++. IMAO nicht sonderlich ernst zu nehmen, auch wenn er wohl so masochistisch ist, und sowas in Produktivcode einsetzt. Zitat:
Aber sicherlich Gewöhnungssache. Zitat:
Zitat:
Zitat:
Zitat:
Was mir spontan einfällt:
Delphi-Quellcode:
Auch nicht schön, aber leider das einzige, was mir einfällt. Ich habe zum Beispiel auch noch keine wirklich schicke Factory in Delphi gesehen (eine Factory für mehr als eine Klasse). Entweder die Objekte müssen sich des Patterns bewusst sein (TDerivedSingleton hat eine eigene Class Function Instance(), oder bereits der Vorfahre muss über die Nachfahren informiert sein. Über eine wirklich elegante Lösung würde ich mich auch freuen, falls jemand eine hat (gescheite Smart Pointer wären dann nur noch das i-Tüpfelchen ;-)).
TAncestorSingleton = class
protected class function _Instance(): TAncestorSingleton; virtual; abstract; end; TDerivedSingleton = class(TAncestorSingleton) public class function Instance(): TDerivedSingleton; protected class function _Instance(): TAncestorSingleton; virtual; override; // oder war das in Delphi ohne "virtual" bei "override"? end; implementation TDerivedSingleton.Instance(): TDerivedSingleton; begin Result := _Instance(); // oder für die ganz ordentlichen: // Result := TDerivedSingleton(_Instance()); end; |
Re: Singletons vererben
Zitat:
Zitat:
2. Das ist wirklich eine gute Idee. Ich kann ja da, wo ich die Oberklasse verwende, dann mit _Instance arbeiten und da wo ich die Unterklasse auch persönlich kenne mit Instance. Das hatte ich völlig übersehen - hatte in die Richtung gedacht, aber war nicht drauf gekommen :wall:. Danke :-) |
Re: Singletons vererben
Zitat:
Da ich die Klassenregistrierung in der Delphi RTL extrem widerlich finde, habe ich alzaimars IntegerDictionary genommen.(Beide wirklich seeehr praktische Klassen, btw:)) Dort habe ich den Pointer auf die jeweilige Meta class (cast auf Integer) als Key abgelegt, der dazugehörige Wert ist die Instanz dieser Klasse.
Delphi-Quellcode:
2 TestKlassen:
type
TSingleton = class protected constructor UglyHiddenCreate; virtual; public class function GetInstance : TSingleton; constructor Create; reintroduce; end; TSingletonClass = class of TSingleton; implementation uses csDictionary, SysUtils; { TSingleton } constructor TSingleton.Create; begin raise Exception.Create('bla bla...'); end; constructor TSingleton.UglyHiddenCreate; begin inherited Create(); end; class function TSingleton.GetInstance: TSingleton; const dictionary : TIntegerDictionary = nil; var key : Integer; pointerToResult : Pointer; begin if not Assigned(dictionary) then dictionary := TIntegerDictionary.Create(); key := Integer(self); if not dictionary.Find(key, pointerToResult) then begin result := UglyHiddenCreate(); dictionary.Add(key, result); end else Result := TSingleton(pointerToResult); end;
Delphi-Quellcode:
Der Beweis:
uses
uSingleton; type TSingletonA = class(TSingleton) end; TSingletonB = class(TSingleton) end;
Delphi-Quellcode:
procedure TestIt(singletonClass : TSingletonClass);
var instance1, instance2 : TSingleton; begin instance1 := singletonClass.GetInstance(); instance2 := singletonClass.GetInstance(); Writeln(Format('%s: instance1 = instance2 is %s', [singletonClass.ClassName(), BoolToStr(instance1 = instance2, True)])); end; begin TestIt(TSingletonA); TestIt(TSingletonB); end. Output TSingletonA: instance1 = instance2 is True TSingletonB: instance1 = instance2 is True edit: Nachdem ich erst tommies Zitat vergass, hatte ich auch noch den TestCode mit dem StringDictionary hier abgeschickt :wall: |
Re: Singletons vererben
Zitat:
|
Re: Singletons vererben
@Elvis: Das einzig interessante an deinem Code ist das Dictionary. Bei Zuweisungen von GetInstance() findet nach wie vor ein Typecast statt. Ich bin immer noch der Meinung, daß die klassische C++-Lösung eleganter ist ;-)
|
Re: Singletons vererben
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:26 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 by Thomas Breitkreuz