INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.


Antwort schreiben 

Dieses Thema hat akzeptierte Lösungen:

Objekte verschiedener Kindklassen vergleichen



Wenn dein Problem oder deine Frage geklärt worden ist, markiere den Beitrag als "Lösung",
indem du auf den "Lösung" Button rechts unter dem entsprechenden Beitrag klickst. Vielen Dank!

01.07.2019, 10:38
Beitrag #14

seuk Offline
LVF-Grünschnabel
*


Beiträge: 38
Registriert seit: May 2018

2019x64
-
EN


Deutschland
RE: Objekte verschiedener Kindklassen vergleichen
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?
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.

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... 2hands Die neue Methode soll nun einen Enum TypeDef empfangen, welcher sowohl den Minimal- als auch den Maximalwert repräsentiert.

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:  
  • 1. Festlegen: Was sieht der Anwender? Was muss/will/kann der Anwender tun während der Dateneingabe? Brauche ich hier in besonderes Datenmanagement?
  • 2. Festlegen: Wie sieht mein Datensatz aus, den ich für die Applikation brauche? Der Datensatz liegt bei mir immer in einem Cluster. Vorteil: ein Wire (in Zahl: 1).
  • 3. Wie sieht das Datenmanagement aus zwischen Punkt 1 und Punkt 2: Der Cluster, der in der Applikation verwendet wird, muss in keinster Weise mit dem identisch sein, den der Anwender sieht (das meine ich mit Trennung des FP von den Daten). Mehrmals hatte ich bereits den Fall, dass der Anwender eine Tabelle ("2D-Arr of String") und einige Einzelwerte gesehen und bearbeitet hat, in der Applikation ist es aber besser zu arbeiten mit einem Cluster, der Einzelwerte, Cluster und ArrOfCluster enthält. Einen "Konverter" zu machen zwischen diesen beiden "Systemen" ist überhaupt kein Problem.

Da bin ich bei dir. Insbesondere Punkt 3 ist hier der springende Punkt Hopper 1 + 2 kann sich ja ständig ändern. Man sollte beim Design immer die Änderbarkeit im Hinterkopf haben, um sich später unnötigen Aufwand zu sparen.

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...
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren to top
Antwort schreiben 


Nachrichten in diesem Thema

Gehe zu: