![]() |
Spring Collections erweitern
Hallo,
ich versuche grade, meine Anwendung mit dem Spring-Framework und Spring Collections zu ergänzen. Ich habe eine Klasse
Code:
Diese möchte ich in eine TQueue<TMyItem> stecken. Dazu habe ich
TMyItem = class
FLaenge: Double; published property Laenge: Double read FLaenge write FLaenge; end;
Code:
So weit so gut. Allerdings erhalte ich jetzt ein Speicherleck, da die einzelnen Items nicht automatisch freigegeben werden. Müsste ich also immer von Hand machen, will ich aber nicht.
TMyQueue = class(TQueue<TMyItem>)
public function Gesamtlaenge: Double; // iteriert über die Items und summiert auf end; ... MyQueue = TMyQueue.Create; MyQueue.Enqueue(TMyItem.Create); Gesamt:=MyQueue.Gesamtlaenge; Im Framework kann man ja auch über
Code:
eine Queue erstellen, die die enthaltenen Items automatisch freigibt. Das funktioniert ja auch. TCollections erzeugt mir allerdings nur eine TQueue, keine TMyQueue, die dann z.b. die Funktion Gesamtlaenge enthält.
TCollections.CreateQueue<TMyItem>(True);
Wie würdet ihr das am besten lösen? Doch von Hand im Destructor freigeben? TCollections vererben und um CreateMyQueue ergänzen? Class Helper Gesamtlaenge für die Klasse TQueue? Scheint mir alles nicht so sauber. Aber da ich mich erst langsam herantaste, sehe ich noch keine gute Lösung. Gruß Rainer |
AW: Spring Collections erweitern
Nur um sich die (für Delphi normale) Freigabe eines aggregierten Objekts im Destruktor (oder woanders) zu sparen steigt man wahrscheinlich nicht auf ein komplett neues Collection-Framework um.
Um ehrlich zu sein, war es bei mir aber ähnlich (Spring Collections sind toll). Von einem Class Helper hast du nichts- Die gehen ja nur für Klassen, Records und einfache Typen (Integer, String, Enums, ...). Interfaces bleiben außen vor. Ich persönlich würde meinen, dass sich es nur für die (ziemlich triviale) Eigenschaft "Summe aller Items bzgl. einer bestimmten Eigenschaft" auch nicht lohnt: In diesem speziellen Fall würde ich (ja, jedes mal) hingehen, über alle Items drüberrutschen und aufsummieren:
Delphi-Quellcode:
implementation uses Spring.Collections;
type TMyItem = class public var länge: Double; end; {$R *.dfm} procedure TForm25.FormCreate(Sender: TObject); var myQueue: IQueue<TMyItem>; gesamtlänge: Double; begin myQueue := TCollections.CreateQueue<TMyItem>(); // [Queue mit Inhalt füllen] gesamtlänge := 0; myQueue.ForEach( procedure(const item: TMyItem) begin gesamtlänge := gesamtlänge + item.länge; end ); ShowMessage( gesamtlänge.ToString() ); end; Ansonsten habe ich ehrlich gesagt auch nie wirklich Scheu davor, einen neuen Typen für meine ganz speziellen Zwecke zu erstellen. Also
Delphi-Quellcode:
Dann sind deine Container nicht mehr vom Typ
type
IMyQueue = interface(IQueue<TMyItem>) function getGesamtlänge(): Double; end; TMyQueue = class( Spring.Collections.Queues.TQueue<TMyItem>, IMyQueue) public function getGesamtlänge(): Double; end;
Delphi-Quellcode:
sondern
IQueue<TMyItem>
Delphi-Quellcode:
IMyQueue
|
AW: Spring Collections erweitern
Von Hand jedesmal drüberrutschen mag ich nicht, das macht den Quelltext ja nicht grad übersichtlicher, wenn die Gesamtlänge ein paar mal gebraucht wird.
Und beim normalen Ableiten krieg ich ja wieder keinen Container, der die Objekte selbst aufräumt. |
AW: Spring Collections erweitern
Wenn du
Delphi-Quellcode:
noch auf
TMyItem
Delphi-Quellcode:
umstellst hast du das Problem nicht ;-)
IMyItem
Ansonsten müsste man sich wieder eine eigene Fabrikmethode "CreateMyQueue" bauen- Die Spring-Queue geht nur bei
Delphi-Quellcode:
auf eine TObjectQueue, ansonsten immer auf eine normale TQueue.
CreateQueue<T: class>(ownsObjects: Boolean): IQueue<T>;
|
AW: Spring Collections erweitern
Ist das das Spring das man aus java kennt? Also Aspekt orientierte Programmierung?
|
AW: Spring Collections erweitern
Die einfachste Lösung wäre ja eine Funktion, die so eine Queue als Parameter nimmt und dann die Gesamtlänge zurückgibt.
|
AW: Spring Collections erweitern
Zitat:
AOP findest du (glaube ich) bei ![]() Für beides ist ![]() PS: Müsste so gehen:
Delphi-Quellcode:
interface type
TMyCollections = class(Spring.Collections.TCollections) public class function CreateMyQueue(ownsObjects: Boolean): IMyQueue; end; implementation uses Spring.Collections.Queues, System.Generics.Collections; class function TMyCollections.CreateMyQueue(ownsObjects: Boolean): IMyQueue; type TOwningQueue = System.Generics.Collections.TObjectQueue<TMyItem>; var objQueue: TOwningQueue; ownership: TOwnershipType; begin objQueue := TOwningQueue.Create(ownsObjects); if ownsObjects then ownership := TOwnershipType.otOwned else ownership := TOwnershipType.otReference; Result := TMyQueue.Create(objQueue, ownership); end; |
AW: Spring Collections erweitern
Erstmal sorry, dass ich den Thread erst jetzt sehe - ich wünschte, es gäb hier Notifications, die man sich für bestimmte Keywords einrichten könnte. :)
Zu deiner Frage: TQueue<T> in Spring4D ist "nur" ein Wrapper um die TQueue<T> aus Generics.Collections, um ihr das IQueue<T> Interface zu verpassen. Das verleiht ihr aber auch die Flexibilität bei Bedarf beide Klassen anpassen zu können. Musst du aber in deinem Fall meiner Meinung nach nicht. Da wir leider in Delphi keine interface helper haben (das wär schön, dann könnte man einfach die Sum Methode aus dem IEnumerable<T> helper nutzen und bumm, fertig). Egal, du benötigst ja hier eine Summe für die Menge einer konkreten Klasse (TMyItem). Das macht es einfach, da du so keine Selector Delegate brauchst, die dir den zu summierenden Wert (in deinem Fall die Laenge) liefert, was du bei einem ![]() Ich würde also folgende simple Lösung vorschlagen, die überhaupt keine Modifikation bestehender Klassen notwendig macht.
Delphi-Quellcode:
Im Grunde ist das auch genau das, was eine extension Method für IEnumerable<TMyItem> machen würde, nur dass man die Dank (in Delphi nicht vorhandenem) syntactic sugar anders aufrufen kann.
function GesamtLaenge(const source: IEnumerable<TMyItem>): Double;
var item: TMyItem; begin Result := 0; for item in source do Result := Result + item.Laenge; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:19 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