AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Delphi Strategie für Propertyvergleich verschiedener Objecte
Thema durchsuchen
Ansicht
Themen-Optionen

Strategie für Propertyvergleich verschiedener Objecte

Ein Thema von Hobbycoder · begonnen am 24. Apr 2017 · letzter Beitrag vom 3. Mai 2017
Antwort Antwort
Hobbycoder

Registriert seit: 22. Feb 2017
930 Beiträge
 
#1

Strategie für Propertyvergleich verschiedener Objecte

  Alt 24. Apr 2017, 10:55
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:
TElement.Name
Telement.id  //eindeutig
TElement.Temperatur
TElement.Luftdruck
TElement.Luftfeuchte
Die Objecte wohnen zur Zeit alles in einer TObjectList.

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:
if (Element[0].Temperatur>18) and ((Element[0].Luftdruck=1) or (Element[1].Temperatur<15)) then Von diesen definierten Aktionen soll es dann x-beliebige gehen, die separat gespeichert werden sollen.

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

Geändert von Hobbycoder (24. Apr 2017 um 11:48 Uhr)
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.110 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: Strategie für Propertyvergleich verschiedener Objecte

  Alt 24. Apr 2017, 11:58
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:
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;
Ich persönlich finde dass gerade die Spring4D-Bibliothek viel mehr Spaß in die Sache bringt weil man hier vernünftige Multicast-Events hat und sich durch nullbare Datentypen dieses krumme "NaN" für die Fließkommazahlen sparen kann.


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.
  Mit Zitat antworten Zitat
Hobbycoder

Registriert seit: 22. Feb 2017
930 Beiträge
 
#3

QLb

  Alt 24. Apr 2017, 12:19
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.
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.
  Mit Zitat antworten Zitat
freimatz

Registriert seit: 20. Mai 2010
1.380 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Strategie für Propertyvergleich verschiedener Objecte

  Alt 25. Apr 2017, 15:14
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.
  Mit Zitat antworten Zitat
Hobbycoder

Registriert seit: 22. Feb 2017
930 Beiträge
 
#5

AW: Strategie für Propertyvergleich verschiedener Objecte

  Alt 25. Apr 2017, 16:05
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.
Ich weiß nicht was du mir mit diesem Post sagen willst.

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?)
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.

Geändert von Hobbycoder (25. Apr 2017 um 16:07 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Olli73
Olli73

Registriert seit: 25. Apr 2008
Ort: Neunkirchen
662 Beiträge
 
#6

AW: Strategie für Propertyvergleich verschiedener Objecte

  Alt 26. Apr 2017, 11:11
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.
Anstatt aus dem UI einen "Text" zu machen und den anschließend zu parsen, könntest du direkt aus dem UI einen Binärbaum zur Auswertung erstellen. Wenn du dort Klassen verwendest und die Eigenschaften published machst, kannst du das auch so direkt abspeichern/laden.
  Mit Zitat antworten Zitat
freimatz

Registriert seit: 20. Mai 2010
1.380 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Strategie für Propertyvergleich verschiedener Objecte

  Alt 3. Mai 2017, 11:02
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 )
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:49 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz