![]() |
Strategie für Propertyvergleich verschiedener Objecte
Der Titel ist nicht ganz eindeutig drum erkläre ich mal was ich machen möchten.
Gegeben ist eine dynamische Menge von Objekten, die jeweils mehrere Eigenschaften haben (können). Diese Eigenschaften lese ich per JSON aus einem entfernten System aus, dessen verhalten ich nicht beeinflussen kann. Beispiel für ein Object:
Code:
Die Objecte wohnen zur Zeit alles in einer TObjectList.
TElement.Name
Telement.id //eindeutig TElement.Temperatur TElement.Luftdruck TElement.Luftfeuchte Nun möchte ich dem User die Möglichkeit geben, bei Eintreten bestimmter Werte Aktionen auslösen zu lassen. Diese Werte soll er aus unterschiedlichen Objecte und unterschiedlichen Eigenschaften zusammensetzen können, und es muss sowohl <Und> als auch <Oder> Bedingungen geben, wobei deren Anzahl nicht vorgegeben sein soll. Als Code-Beispiel würde das so aussehen:
Delphi-Quellcode:
Von diesen definierten Aktionen soll es dann x-beliebige gehen, die separat gespeichert werden sollen.
if (Element[0].Temperatur>18) and ((Element[0].Luftdruck=1) or (Element[1].Temperatur<15)) then
Ich zerbreche mir schob einige Zeit den Kopf, wie ich sowas in eine Klasse packen kann, so dass diese sich selber auswerten kann und dann ggf. ein True zurück liefert. Mein Problem sind a) dass es je mehrer Bedingungen geben soll, und b) diese auch noch unterschiedlich (und/oder) miteinander verknüpft sein sollen. Bin für jeden Anreiz dankbar. Gruß Hobbycoder |
AW: Strategie für Propertyvergleich verschiedener Objecte
Ich gehe mal davon aus dass Json und Objektlisten damit an sich nichts zu tun haben. Du hast ein Objekt. Das Objekt hat Eigenschaften. Du möchtest mitbekommen wenn sich diese Eigenschaften ("Properties") ändern bzw. Werte aufweisen die aufgestellte Kriterien verletzen.
Verpasse doch den Property-Settern einfach das Prüfen auf ein Kriterium. Das Kriterium selbst ist ein Objekt bzw. Record. Hier einmal beispielhaft für Luftdruck und Temperatur, min und max.
Delphi-Quellcode:
Ich persönlich finde dass gerade die
uses
System.SysUtils, System.Classes; TElementChangeCriteria = record /// <remarks> /// <c>NaN</c> für "nicht vorhanden" /// </remarks> minTemperature: Single; /// <remarks> /// <c>NaN</c> für "nicht vorhanden" /// </remarks> maxTemperature: Single; /// <remarks> /// <c>NaN</c> für "nicht vorhanden" /// </remarks> minLuftdruck: Single; /// <remarks> /// <c>NaN</c> für "nicht vorhanden" /// </remarks> maxLuftdruck: Single; public class function None(): TElementChangeCriteria; static; end; TElement = class private var FName: String; FTemperatur: Single; FLuftdruck: Single; private procedure setTemperatur(const Value: Single); procedure setLuftdruck(const Value: Single); protected function criteriaMet(): Boolean; virtual; procedure checkEventCriteria(); public var eventCriteria: TElementChangeCriteria; OnCriteriaEvent: TNotifyEvent; public property Name: String read FName; property Temperatur: Single read FTemperatur write setTemperatur; property Luftdruck: Single read FLuftdruck write setLuftdruck; end; { TElementChangeCriteria } class function TElementChangeCriteria.None(): TElementChangeCriteria; begin Result.minTemperature := Single.NaN; Result.maxTemperature := Single.NaN; Result.minLuftdruck := Single.NaN; Result.maxLuftdruck := Single.NaN; end; { TElement } procedure TElement.checkEventCriteria(); begin if criteriaMet() then if Assigned(OnCriteriaEvent) then OnCriteriaEvent(self); end; function TElement.criteriaMet(): Boolean; begin if not eventCriteria.minTemperature.IsNan() then if (eventCriteria.minTemperature >= Temperatur) then Exit(True); if not eventCriteria.maxTemperature.IsNan() then if (eventCriteria.maxTemperature <= Temperatur) then Exit(True); if not eventCriteria.minLuftdruck.IsNan() then if (eventCriteria.minLuftdruck >= Luftdruck) then Exit(True); if not eventCriteria.maxLuftdruck.IsNan() then if (eventCriteria.maxTemperature <= Luftdruck) then Exit(True); Result := False; end; procedure TElement.setLuftdruck(const Value: Single); begin FLuftdruck := Value; checkEventCriteria(); end; procedure TElement.setTemperatur(const Value: Single); begin FTemperatur := Value; checkEventCriteria(); end; ![]() In Sachen Bedienung: Ich weiß nicht wie technik-affin deine Benutzer sind mit Querys wie "someCondition OR otherCondition AND finalCondition" kommen viele nicht gut zurecht. Ich würde einfach einen Frame mit Edit-Boxen und Text-Feldern machen der dann eine TElementChangeCriteria zurückgibt. |
QLb
Erst mal vielen Dank für deine Anregung.
Das ich als Trigger die Setter verwenden kann, das hatte ich auch schon vorgesehen. Mir ging es ehr darum, wie ich die Menge an verschiedenen Kriterien komfortabel in eine Klasse packen könnte, so dass und/oder-Bedingungen unter diesen Kriterien auch noch möglich sind. (Vielleicht habe ich mich da im Ursprungsbeitrag etwas unglücklich ausgedrückt). Meine Einzige Idee zur Zeit wäre, das ganze in eine String ala SQL-Syntax zu packen, und diesen bei Verwendung wieder zu parsen. Das Userinterface würde ich ähnlich aufbauen, wie man das von Access kennt (Combobox zur Elementauswahl, Combobox zur Eigenschaftaufwahl, Combobox für Vergleichsoperator und Edit für die Bedingung). Wenn jetzt alles Und-Verknüpfungen oder Oder-Verknüpfungen wären, dann wär's ja nicht so schwierig. Aber ich will ja, dass man die Möglichkeit hat das nach Belieben zu mischen. Und da kommen dann Klammern in Spiel, was die Sache für mich so kompliziert macht. Und da auch nicht nur die Eigenschaften eines Elements untereinander als Kriterien verwendet werden, sondern alle Eigenschaften aller Elemente in einer Anfrage vorhanden sein können, kann ich zwar den Setter als Trigger verwenden, aber nicht innerhalbe des Elements gleiche die ganze Abfrage durchführen. Deswegen will ich die Abfrage in separaten Klassen halten, und sie Setter der Elemente lösen einen Event aus, der seinerseits dann die Abfragen benachrichtigt, die ihrerseits dann bei Erfüllung wieder einen Event auslösen. Mir geht es also um ein solches Klassendesign. |
AW: Strategie für Propertyvergleich verschiedener Objecte
Na ja, irgendwie werde ich nicht so schlauf draus was du willst.
Einerseits ein Klassendesign, weiter oben gibt es ja schon einige Klassen. Dann wiederum schreibst du von "String ala SQL-Syntax" und weiter von einem Userinterface ähnlich Access. Wenn ich das so lese dann braucht du kein Klassendesign sondern eine Architektur. Und wenn ich dann noch "Hobbycoder" sehe, weiß ich nicht mehr wie das zuammenpassen soll. |
AW: Strategie für Propertyvergleich verschiedener Objecte
Zitat:
a) ich habe oben EINE Beispielklasse gepostet, damit man erkennen kann in welcher Form die Daten vorliegen könnten. b) Etwas Klassendesign kam von Günter c) es geht ja gerade darum erst mal eine Idee zu entwickeln, solch Userdefiniete, parameterisierte Anfragen am besten zu hinterlegt, bzw. wie die Vergleichsalgorithmen sinnvoll in Klassen untergebracht werden können, um einfache und verschachtelte Algorithmen zu speichern. Und da könnte ein Syntax mit passendem Parser durchaus sinnvoll sein. d) Da es Userdefiniert sein soll braucht es auch ein UI, das einfach verständlich ist. Das ist auch gut mit Punkt c zu vereinbaren. e) Ich wüsste nicht was mein Nickname damit zu tun hätte. Schon erst mal gar nicht lässt dieser Rückschlüsse auf meine Person oder meine Qualifikation zu. (ich hätte da auch KaterKarlo oder MarcoCantu als Nick nehmen können. Hätte das was an deinem Kommentar geändert?) |
AW: Strategie für Propertyvergleich verschiedener Objecte
Zitat:
|
AW: Strategie für Propertyvergleich verschiedener Objecte
Richtig. Und in dieem Fall braucht man dann keinen Parser mehr.
Bei "es geht ja gerade darum erst mal " hat es sich bei der professionellen Softwareentwicklung durchgesetzt erstmal abzuklären was der Kunde will. Natürlich ist es auch gut abzuschätzen was überhaupt geht. Und damit zu "Hobbycoder": es war nicht meine Absicht dein Können in Frage zu stellen. Aber dein Tag hat auch nur 24 Stunden. In meiner Firma haben wir einen Parser für solche Ausdrücke. Aus der Erfahrung halte ich sowas für etwas zu aufwendig für einen Hobbycoder. Sorry wenn das nicht das ist was du hören willst (Kathinka rulez :)) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:16 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