Hi zusammen,
ich weiß nicht, ob das überhaupt geht, bzw. ob es sich lohnt.
Folgendes Szenario:
Im Programm ( schon eher ein komplettes Framework) haben verschiedene Formulare Grids, die Daten aus den Datenbanken (REST Server) anzeigen.
Die Konfiguration der Spalten sind in der Datenbank abgelegt. Das komplette Design.
Die verschiedenen Programteile haben ein je Model (mal ganz einfach ausgedrückt). Wenn ich dort die Design Infos jedesmal laden würde, kostet das zu viel Geschwindigkeit/Ressourcen. Die Models werden manchmal nur für sehr kurze Zeit (z.B. eine Abfrage) erzeugt und wieder freigegeben.
Also habe ich das Design in ein Singleton Object ausgelagert, das die Daten erst beim ersten Zugriff liest und dann vorhält. Da jedes Programmteil verschiedene Designs benötigt, hält das Singleton Object alle Designs für diesen Bereich.
(Es gibt zu viele Bereiche bzw. Kundenkonfigurationen, als dass man ALLE Designs in EINEM Singlton Object definieren könnte)
Gut. Ich habe also in jedem Model ein Singleton für diesen Bereich.
Das funktioniert auch alles sehr gut.
Der Einfachheit beim Entwickeln (es arbeiten auch andere Personen daran), wollte ich eine Singleton Basisklasse schaffen, von der die anderen ableiten können.
Und das funktioniert nicht.
Hier die Frage von oben nochmal: ich weiß nicht, ob das überhaupt geht,
bzw. ob es sich lohnt.
Hier der Code
Basisunit
Delphi-Quellcode:
type
TsngColumnDescription = class
private
class var FInstance: TsngColumnDescription;
private
FsngColumnsOwner: TsngColumnsOwner;
protected
function GetSngColumnsOwner: TsngColumnsOwner; virtual; // abstract;
public
class function this: TsngColumnDescription; virtual;
class destructor Destroy;
property CD: TsngColumnsOwner read GetSngColumnsOwner;
end;
implementation
{ TsngColumnDescription }
class destructor TsngColumnDescription.Destroy;
begin
if Assigned( FInstance) then begin
FInstance.FsngColumnsOwner.Free;
FreeAndNil( FInstance);
end;
end;
class function TsngColumnDescription.this: TsngColumnDescription;
begin
if not Assigned( FInstance) then begin
FInstance := TsngColumnDescription.Create;
FInstance.FsngColumnsOwner := TsngColumnsOwner.Create;
end;
Result := FInstance;
end;
function TsngColumnDescription.GetSngColumnsOwner: TsngColumnsOwner;
begin
Result := FsngColumnsOwner;
end;
Eine Ableitung in einer anderer Unit
Delphi-Quellcode:
type
TColKaoPfand = class( TsngColumnDescription)
protected
function GetSngColumnsOwner: TkaoPfandColumnDescription; reintroduce;
public
class function this: TColKaoPfand; reintroduce;
property CD: TkaoPfandColumnDescription read GetSngColumnsOwner;
end;
implementation
class function TColKaoPfand.this: TColKaoPfand;
begin
Result := TColKaoPfand( inherited this);
end;
function TColKaoPfand.GetSngColumnsOwner: TkaoPfandColumnDescription;
begin
Result := TkaoPfandColumnDescription( inherited GetSngColumnsOwner);
end;
Ein Zugriff auf "TColKaoPfand.this.CD.xxx" mach eine
ACCESS VIOLATION
Beim debuggen, werden diese Routinen durchlaufen
TColKaoPfand.this (begin ...)
-- TsngColumnDescription.this (begin..end)
TColKaoPfand.this (..end)
TColKaoPfand.GetSngColumnsOwner (begin..)
-- TsngColumnDescription.GetSngColumnsOwner (begin..end)
TColKaoPfand.GetSngColumnsOwner (..end)
sobald er nun aus der letzten procedure raus springt, kommt die
Exception. Also F7/F8 auf der letzten Zeile TColKaoPfand.GetSngColumnsOwner "end;"
Wie gesagt, ohne Ableitung/Vererbung funktioniert das einwandfrei.
Sieht da jemand den Fehler oder ist das vielleicht alles Chaos?
Danke euch
VG Thomas