![]() |
Objekte verschiedener Kindklassen vergleichen - Druckversion +- LabVIEWForum.de (https://www.labviewforum.de) +-- Forum: LabVIEW (/Forum-LabVIEW) +--- Forum: LabVIEW Allgemein (/Forum-LabVIEW-Allgemein) +---- Forum: LVOOP (/Forum-LVOOP) +---- Thema: Objekte verschiedener Kindklassen vergleichen (/Thread-Objekte-verschiedener-Kindklassen-vergleichen) Seiten: 1 2 |
RE: Objekte verschiedener Kindklassen vergleichen - seuk - 27.06.2019 16:13 Vielen Dank für deine ausführliche Antwort! (27.06.2019 14:19 )IchSelbst schrieb: Ich gehe davon aus, du verstehst, was ich meine und wie es funktioniert.Sehr optimistisch, aber danke für das Vertrauen. (27.06.2019 14:19 )IchSelbst schrieb:Wird da nun ein Variant, ein Cluster, oder ein TypeDefCluster übergeben? Kennst du eine Möglichkeit mit Variants Typsicherheit während der Edittime zu gewährleisten? Variant Lookupt Tables sind ja sehr performant, aber es kommen halt Variants raus und ob am Variant To Data der richtige Datentyp angeschlossen war, seh ich erst zur Laufzeit - das erscheint mir doch ein sehr großer Nachteil. (27.06.2019 14:19 )IchSelbst schrieb:Ich bin mir nicht sicher, ob ich diesen ClustersaurusRex sehen möchte. Ich kann mir kaum vorstellen, wie der für einen Anwender gut zu bedienen ist, oder wie das FP von VIs aussehen, die davon einen Wert benötigen. Ich stelle mir eine Anwendung vor, bei dem es 120 Settings gibt und ein VI, welches davon genau 1 benötigt. Wie debuggt man das? Woher weiß man, welche Werte wo geändert werden? (27.06.2019 14:19 )IchSelbst schrieb:Was die Performance angeht bin ich bei dir. Ich möchte kein Dictionary mit 360k Wörtern aufbauen und muss darin super schnell suchen können. In dem Fall ist mir Performance also auch nicht wichtig. Aber das Modul soll auf eine Werteänderung spezifisch reagieren können. Manchmal ist das nur ein Parameter, der sowieso schon an einem SubVI angeschlossen ist und sobald der geändert wurde, rechnet das SubVI halt anders. Dann ist es natürlich kein Problem. Aber wenn ich von einer HW in einem DropDown auf eine andere HW wechsel, muss das Modul schon etwas mehr machen und sollte genau in einen Case hüpfen, der die nötigen Aufgaben abarbeitet. (27.06.2019 14:19 )IchSelbst schrieb:Soweit kann ich folgen, ob ich da eine FGV oder ne Klasse nehme, dürfte ja keinen großen Unterschied machen. (27.06.2019 14:19 )IchSelbst schrieb:Widerspricht sich das nicht mit der Trennung der Daten vom Frontpanel? Wie kannst du deine FGV testen und laufen lassen, ohne das ein FP dazu läuft? Dann hast du doch keine Referenz...? Wie implementierst du eine andere GUI für das gleiche Modul? (27.06.2019 14:19 )IchSelbst schrieb: Jetzt bin ich aber doch baff. Du hast für jedes Modul einen eigenen Settingseditor als FGV implementiert. In dem Fall kann die Reaktion auf eine Werteänderung natürlich direkt in der FGV passieren. Aber dann gibt es keine Trennung zwischen den Settings und dem Modul. Wie gehst du mit Settings um, die Auswirkungen auf mehrere Module haben? In welchem Cluster / FGV stehen die dann? Zumindest wird ein Settingscluster dadurch, dass er nur für ein Modul zuständig ist kleiner. Fraglich ist natürlich auch, was überhaupt ein Modul ist. Ich habe ein Modul für die GUI, eins für die Datenerfassung, eins für Logging und eben eins für die Settings dieser Applikation, also aller Module. Damit hab ich auch nur ein XML File, welches die gesamte Anwendung konfiguriert. Für heute mache ich Feierabend, aber ich werde nochmal darüber nachdenken, was für Vor- und Nachteile ein Settingseditor für die gesamte Anwendung im Vergleich zur Implementierung in jedem einzelnen Modul hat. (27.06.2019 14:45 )IchSelbst schrieb: Jawohl! Mir ist da sofort das programmatische Erstellen von Anzeige/Bedienelementen zur Laufzeit in den Sinn gekommen. Leider kennt LV sowas nicht. Noch kurz zu deinem letzten Beitrag:
Ich denke allerdings, dass es eine Möglichkeit gibt, mit der das Speichern dieser neuer Info im Schieberegister des Settingseditor nicht erweitert muss. Das Speichern und Laden der XML-Datei muss ich so auch nicht anpassen. RE: Objekte verschiedener Kindklassen vergleichen - IchSelbst - 27.06.2019 23:21 (27.06.2019 16:13 )seuk schrieb: Wird da nun ein Variant, ein Cluster, oder ein TypeDefCluster übergeben?Übergeben wird das, was die Methode verlangt. Wenn der ganze Settingsdatensatz in de FGV soll (Methode SetAllData), dann wird ein Cluster an den Variant-Eingang angehängt. Da die FGV den Typ des Datensatzes kennt, kann die Methode SetAllData mit dem Element VariantToData, das zum Konvertieren ja einen Typeingang hat, aus dem Variant die Daten wieder als Cluster herausholen. Verlangt die Methode z.B. nur einen Double (z.B. TempMin), kommt ein Double an den Eingang, der Typ Double an den VariantToData und schon ist ein einzelner Wert (nämlich TempMin) in die FGV gekommen (und die könnte den jetzt in den Settingsdatensatz schreiben ...) Zitat:Kennst du eine Möglichkeit mit Variants Typsicherheit während der Edittime zu gewährleisten?1. Was meinst du denn mit Edittime? Den Zeitpunkt, zu dem das Programm geschrieben wird? Also die Entwicklungszeit als Gegenteil von Runtime? 2. Wenn zur Entwicklungszeit: Du weißt als Entwickler doch, welchen Typ du anschließt - und welchen nicht. Warum dann Typsicherheit gewährleisten? Das verstehe ich nicht: Wenn ein ganz bestimmter Typ am Variant anliegen soll, warum dann einen Variant nehmen? Dann kannst du doch gleich den Originaltyp übergeben? 3. Der Variant ist doch gerade dazu da, verschiedene Typen anschließen zu können. Zitat:Ich bin mir nicht sicher, ob ich diesen ClustersaurusRex sehen möchte.120 Parameter müssen nicht in einem Cluster liegen. Dafür hab ich ja idealerweise geschrieben. So ein FGV kann statt einem Cluster auch 20 Cluster verwalten. Jeder der Zwanzig würde dann auf einem Reiter eines TabControls liegen. Zitat:Ich stelle mir eine Anwendung vor, bei dem es 120 Settings gibt und ein VI, welches davon genau 1 benötigt.Wenn du 120 Parameter hast und nur einen brauchst, zeigt dann dein SettingsModul 120 Parameter an oder den einen? Woher weiß das Settingsmodul welcher der eine ist? Zitat:Aber wenn ich von einer HW in einem DropDown auf eine andere HW wechsel, muss das Modul schon etwas mehr machen und sollte genau in einen Case hüpfen, der die nötigen Aufgaben abarbeitet.Selbstverständlich kann meine FGV sowas: Einmal direkt mit einer speziellen Methode und der Übergabe dieses einen Wertes im Event-Case "SettingsCluster.HW-DropDown(ValueChange)". Außerdem geht das auch indirekt, indem in der Methode SetAllData der neue Wert HW-DropDown mit dem alten verglichen wird. Zitat:ob ich da eine FGV oder ne Klasse nehme, dürfte ja keinen großen Unterschied machen.Genau, deswegen heißen ja auch FGV "Klasse für kleine Leute" (Zitat von RolfK). Zitat:Widerspricht sich das nicht mit der Trennung der Daten vom Frontpanel?Nein. In 99% der Fälle schreibt die FGV die Daten per Referenz und Eigenschaftsknoten Value in diesen Cluster - nur damit der Anwender was sieht. Ausgelesen wird dieser Cluster nicht. Zitat:Wie kannst du deine FGV testen und laufen lassen, ohne das ein FP dazu läuft?Da läuft ja ein FP - das von der FGV. Da gibt es eigentlich nicht viel zu debuggen. Es kommen Daten herein, die gespeichert werden. Und Datenverarbeitung findet nicht in diesem VI statt, sondern in einem Unterprogramm ... Zitat:Du hast für jedes Modul einen eigenen Settingseditor als FGV implementiert.Wo liegt das Problem? Schließlich bin ich Programmierer ... ![]() Zitat:Aber dann gibt es keine Trennung zwischen den Settings und dem Modul.Genau das ist Sinn und Zweck: Datenkapselung ... Zitat:Wie gehst du mit Settings um, die Auswirkungen auf mehrere Module haben?So einen Fall habe ich noch nicht gehabt. Die würden bei mir dann wohl ein eigenes Modul (einschließlich FGV) sein oder nur eine FGV namens S1. Die Module M1, M2, M3 hätten dann eigene FGVs Mx und wären berechtigt die Daten von S1 zu verwenden. Wie ein ValueChange dann an die Module Mx käme, müsste ich noch überlegen. Zitat:Ich habe ein Modul für die GUI, eins für die Datenerfassung, eins für Logging und eben eins für die Settings dieser Applikation,Ja, das hab ich auch so. Bei mir haben diese Module alle 5 maximal 50 Parameter. Von den FGVs im Hintergrund sieht der Anwender ja nichts. Der sieht nur ein TabControl mit vielen Reitern, auf denen alle Daten verteilt sind. Wenn du 120 Parameter hast, was sieht denn der Anwender? Sieht der alle verfügbaren Parameter, praktisch am Stück, wenn auch über mehrere Reiter verteilt, so wie bei mir? Was ich mir auch und gerade bei 120 Parametern vorstellen könnte, wäre eine "indizierte Eingabe": Der Anwender sieht zwei Eingabeelemente. Ein Pulldown (Ring) in dem alle Parameter mit Klartextbezeichnung aufgeführt sind. Dann sieht er rechts daneben ein Eingabefeld (Typ String, der kann alles). Der Anwender sucht sich aus dem Ring den Parameter, den er ändern will. Dann gibt er im Eingabefeld den neuen Wert ein. Mit diesem Verfahren bist du unabhängig von jedwedem Clustertyp. Du kannst für jeden Parameter im Ring einen standardisierten Datensatz definieren, der z.B. Quelle und Ziel des Parameterwertes enthält. Und den Typ des Parameters samt Wertebereich. etc. Dieses Verfahren wäre soweit abstrahierbar, dass Typ und Anzahl der Parameter egal wären. Hat nur einen Nachteil: Der Anwender muss diesem Eingabeverfahren zustimmen. Möglicherweise ist ein Zwischending möglich: Das würde auf einen standardisierten, komplexen Datentyp (Cluster) hinauslaufen z.B. "Sollwert mit Grenzen": Cluster aus 3 DBL. RE: Objekte verschiedener Kindklassen vergleichen - IchSelbst - 28.06.2019 08:47 Ich hab schon wieder was wichtiges vergessen zu schreiben: Folgendes Vorgehen halte ich für ganz wichtig, egal ob du FGV oder OOP machst:
"Applikation" ist in deinem Falle das Settingsmodul. In deinem Falle, nämlich ein vom Datensatz abstrahiertes Settingsmodul, muss der Punkt 3 gewissenhaft bedacht werden - unabhängig ob OOP oder FGV. Natürlich muss du hier auch Vorausschau betreiben (was du ja gemacht hast): Was ist, wenn ich das SettingsModul erweitern muss? Wird das gehen? Wie schwierig wird das sein? In deinem Falle muss auch genau geklärt werden, was denn Punkt 2 genau ist: der original Datensatz diverser Module? Oder dieser originale Datensatz zusammen mit einem Beschreibungsdatensatz (dass das dann praktisch zwei Datensätze sind, ist irrelevant). Den Beschreibungsdatensatz muss das diverse Modul liefern - nur das weiß nämlich, wie seine eigenen Daten beschrieben werden müssen. Allerdings wird die Struktur des Beschreibungsdatensatzes vom Settingsmodul bestimmt. Diese Überlegungen müssen vor dem Start der Programmierung geschehen, um die unnützen Zeiten während der Programmierung zu minimieren. Im Normalfall sind diese Überlegungen innerhalb einer Zigarettenlänge (oder Kaffeepause, wer dieser Droge frönt) erledigt. Nicht aber bei einem abstrahierten Modul. RE: Objekte verschiedener Kindklassen vergleichen - seuk - 01.07.2019 10:38 Nochmals Danke für die detaillierten Ausführungen. (27.06.2019 23:21 )IchSelbst schrieb: 1. Was meinst du denn mit Edittime? Den Zeitpunkt, zu dem das Programm geschrieben wird? Also die Entwicklungszeit als Gegenteil von Runtime? Die Typsicherheit zur Edittime finde ich sehr wichtig. Ich meine damit genau wie du es verstanden hast, die Entwicklungszeit im Gegensatz zur Runtime. Zu dem Zeitpunkt weiß ich als Entwickler, dass ich z.B. der Methode SetTempMin() den Double-Wert als Variant übergeben kann und in der FGV im entsprechenden Case den Variant auch wieder in ein Double zurück caste. Nun stell dir aber vor, dass drei Jahre später ein anderer Entwickler auf die Idee kommt statt SetTempMin() und SetTempMax() eine einzige Methode SetTempThresholds() einzuführen. Aus Gründen... ![]() Nun sind direkt zwei Sachen passiert: 1. statt eines DBL wird ein Enum verwendet und 2. die beiden Methoden gibt es gar nicht mehr. Zu 1.: Bei der Verwendung einer Klasse existieren zwei VIs für die beiden Methoden. Ändere ich nun den Eingang von einem DBL zu einem Enum, "brechen" sofort alle VIs, in denen die Methode verwendet wird. Ich habe einen Fehler in der Entwicklungszeit, welchen ich schnell finden und beheben kann. Bei einem Variant-Eingang sind alle VIs weiterhin lauffähig - erst zur Laufzeit wirft VariantToData einen Fehler, da der Variant in dem noch immer ein DBL übergeben wurde, nicht zu einem Enum gewandelt werden konnte. Ich möchte also den Originaltyp verwenden und kein Variant. Bei deinem Konstrukt muss es ja ein Variant sein, da die FGV nur zwei Eingänge hat (Enum + Variant). Oder habe ich das falsch verstanden? Zu 2. : Mit OOP lösche ich die beiden VIs und wieder "brechen" alle Stellen an denen sie verwendet wurden und an denen die neue Methode verwendet werden soll. Dieser Fall wäre kein Problem mit einer FGV, denn der Enum, der dem Methodenaufruf entspricht (also auch ein Eingangsparameter der FGV ist), der ist ja an eine Typdefinition gebunden. Wenn dort die beiden Einträge SetTempMin und SetTempMax entfernt werden kommt es auch zu Fehlern, die VIs sind nicht lauffähig. Stell dir vor du bemerkst, dass in einem Setting ein Wert drin steht, den du dir nicht erklären kannst. Nun möchtest du alle Programmstellen inspizieren, an denen der Wert in die FGV geschrieben wird. Du kannst nach deiner FGV suchen, aber findest damit alle Stellen. Um den Originaltyp zu verwenden und alle Stellen im Code finden zu können, muss man Wrapper VIs für jede Methode bauen und nicht direkt auf die FGV zugreifen. Das würde ich dir empfehlen, um die oben genannten Vorteile zu erreichen. Am besten die FGV privat machen, so dass vom restlichen Programm gar nicht darauf zugegriffen werden kann. (27.06.2019 23:21 )IchSelbst schrieb: Wenn du 120 Parameter hast und nur einen brauchst, zeigt dann dein SettingsModul 120 Parameter an oder den einen? Woher weiß das Settingsmodul welcher der eine ist? Das war anders gemeint. Die gesamte Anwendung hat 120 Settings, eine davon ist z.B. die Abtastungsrate. Nun haben wir geschickterweise die 120 nicht alle in einem einzigen Cluster, doch die Abtastungsrate steckt noch immer sagen wir mal mit 20 anderen in einem Cluster. Es wäre gut einem VI welches nun mit den Messwerten rumrechnet und nur die Abtastungsrate benötigt, auch nur diese zu übergeben und nicht den gesamten Cluster. Bei einem simplen unbundle kann ich diese Stellen nicht leicht finden, dafür bräuchte man wieder ein extra VI getRate()... (27.06.2019 23:21 )IchSelbst schrieb: Wenn du 120 Parameter hast, was sieht denn der Anwender? Sieht der alle verfügbaren Parameter, praktisch am Stück, wenn auch über mehrere Reiter verteilt, so wie bei mir?Reiter sind gut, 120 Parameter auf einem FP gleichzeitig sind sicherlich nicht bedienerfreundlich. Gut finde ich außerdem, wenn Einstellungen über mehrere Wege im Programm zu erreichen sind. So wie man z.B. in einer Textverarbeitung die Schriftfarbe im Menü ändern kann, aber auch indem man ein Wort markiert und ein PopUpMenü erhält. (27.06.2019 23:21 )IchSelbst schrieb: Was ich mir auch und gerade bei 120 Parametern vorstellen könnte, wäre eine "indizierte Eingabe": Der Anwender sieht zwei Eingabeelemente. Ein Pulldown (Ring) in dem alle Parameter mit Klartextbezeichnung aufgeführt sind. Dann sieht er rechts daneben ein Eingabefeld (Typ String, der kann alles). Der Anwender sucht sich aus dem Ring den Parameter, den er ändern will. Dann gibt er im Eingabefeld den neuen Wert ein. Mit diesem Verfahren bist du unabhängig von jedwedem Clustertyp. Du kannst für jeden Parameter im Ring einen standardisierten Datensatz definieren, der z.B. Quelle und Ziel des Parameterwertes enthält. Und den Typ des Parameters samt Wertebereich. etc. Dieses Verfahren wäre soweit abstrahierbar, dass Typ und Anzahl der Parameter egal wären. Hat nur einen Nachteil: Der Anwender muss diesem Eingabeverfahren zustimmen. Möglicherweise ist ein Zwischending möglich: Das würde auf einen standardisierten, komplexen Datentyp (Cluster) hinauslaufen z.B. "Sollwert mit Grenzen": Cluster aus 3 DBL.Das würde ich einem Benutzer niemals zumuten. Der Parameterring ist unübersichtlich, die Eingabe als Text nicht komfortabel und Fehleranfällig. (28.06.2019 08:47 )IchSelbst schrieb: Da bin ich bei dir. Insbesondere Punkt 3 ist hier der springende Punkt ![]() Nun sind wir aber ganz schön vom Thema und ins Grundsätzliche abgekommen. Nicht, dass ich das nicht wertschätze! Aber ich habe mein Problem ja auch nochmal mit einem Minimalbeispiel verdeutlicht. Hat da niemand eine Idee? (27.06.2019 14:28 )seuk schrieb: Wie kann ich das so lösen, dass im SaveCase nichts angepasst werden muss, wenn weitere Settings hinzukommen bzw. deren Namen oder Typen geändert werden? Das sollte doch mithilfe von Dynamic Dispatch möglich sein, indem ein Array der Elternklasse durchlaufen wird und eine konkretes VI einer Kindklasse aufgerufen wird, welches genau die drei Schritte enthält... RE: Objekte verschiedener Kindklassen vergleichen - seuk - 18.07.2019 14:15 Ich habe es nun hinbekommen. Anbei meine Lösung für Interessierte. Nur ganz kurz beschrieben:
[attachment=60209] [attachment=60210] |