Hallo zusammen,
zuerst möchte ich mich für den recht unspezifischen Thread-Titel
entschuldigen; leider lässt sich das Thema nicht so knapp
zusammenfassen.
Bei einem aktuellen Projekt kommt folgender Code (stark vereinfacht und
gekürzt) zum Einsatz:
Dieser dient dazu, auf einfache Art und Weise viele verschiedene Klassen
mit unterschiedlichen Attributen anzulegen, wie z.B. im nachfolgenden
Beispiel:
Die Werte einzelner Attribute können sich ändern, die Bezeichnungen,
Minimal-, Maximal- und Default-Werte bleiben jedoch immer konstant und
werden lediglich für die Validierung von Eingaben, GUI-Ausgaben, etc.
verwendet.
Und nun komme ich auch endlich zu der Problematik/Frage:
Jede Instanz von "Car" hält diese konstanten Werte redudant vor, was es
zu vermeiden gilt. Gleichzeitig möchte ich eine möglichst einfache
Syntax bei der Definition der einzelnen Klassen beibehalten und suche
hier nach einer eleganten Lösung (es existieren knapp hundert
verschiedene Klassen, die wiederum auch wieder bis zu 50 "Attribute"
enthalten; auch existieren verschiedene Attribut-Typen mit
unterschiedlichen Constraints, Datentypen, etc.).
Viele Grüße,
Peter
Moin,
wenn da Standarddaten sind, die sich nicht so oft ändern und für
Validation benutzt werden, dann lager sie aus. Die müssen nicht
unbedingt in der Klasse lagern. Schreib sie in eine separate Datei, die
du einliest.
Dein "Attribute_Set" enthält also Pointer/Referenzen zu den eigentlichen
privaten Member-Variabeln? Was ist jetzt genau das Problem? Wenn nicht
jede Instanz von "Car" eine eigene Kopie davon haben soll könntest Du
sie "static" machen. Dann sollte jede Instanz auf die selben Daten
zurückgreifen. Oder Du bastelst eine extra Klasse für diese
Informationen und in "Car" dann eine Referenz darauf.
Außer bei "length" und "witdh" seh ich da auf den ersten Blick nicht
wahnsinnig viele doppelte Werte. Mal davon abgesehn sind wir hier im
Forum "PC-Programmierung", selbst bei 100 Instanzen mit jeweils 50
Attributen wären statische min/max float-Werte lediglich 40kBytes.
Ansonsten besteht natürlich jederzeit die Möglichkeit aus FP_Attribute
ein Template zu machen und die min/max Werte als Typ zu übergeben und
innerhalb der Klasse als statisch zu deklarieren. Jede Template-Instanz
mit den selben Template-Parametern nutzt dann die selben statischen
Werte.
Man beachte, dass ich oben von "Typ" und nicht von "float" gesprochen
hab. Leider unterstützen Templates laut Standard keine Gleitkomma
Parameter, weshalb man jedes min/max Paar in einen eigenen Typen wrappen
müsste.
Vermutlich gibts noch schlauere Methoden... ad-hoc fällt mir aber grad
keine ein. :)
Ich denke, das Problem verstanden zu haben.
Dein FP_Attribute enthält Wert, Name, Minimum und Maximum. Für jedes
Attribut sind die verschieden. Nun gibt es mehrere Instanzen von Car,
die die gleichen Attribute haben, wo sich pro Car nur die Werte
unterscheiden, aber in jedem Car haben sie die gleichen Namen, Minimum
und Maximum.
Also so in etwa:
Car1 hat {"Länge", 4.8, 0.1, 10.0}
Car2 hat {"Länge", 4.2, 0.1, 10.0}
Car3 hat {"Länge", 4.3, 0.1, 10.0}
Car4 hat {"Länge", 3.9, 0.1, 10.0}
Und da für sämtliche Cars alles außer dem zweiten Element des Attributes
immer gleich ist, willst du die Redundanz los werden.
Da würde mir nur einfallen, den Wert und die anderen Elemente des
Attributs in zwei getrennte Klassen zu stecken und in der
"Attribut-Werte"-Klasse dann auf die "Attribut-Eigenschaften"-Klasse zu
referenzieren.
Die Variante von Vincent Hamp sollte auch gehen, hat aber den Nachteil,
dass dann alle Attribute von unterschiedlichen Typen sind und man sie
somit nicht mehr einfach in einen Container stecken und darüber
iterieren kann.
PS: Welches Auto ist denn eigentlich nur 10 cm lang ;-)
Vielen Dank für die vielen Beiträge!
Ich war gerade dabei, das Problem etwas genauer zu beschreiben, habe
jedoch eben gesehen, dass Rolf Magnus es sehr schön auf den Punkt
gebracht hat. Genau darum ging es mir.
@Vicent Hamp
Das Problem sind in der Tat nicht die 100 Klassen und auch nicht die bis
zu 50 "Attribut"-Member. Dies hatte ich nur erwähnt, um deutlich zu
machen, dass die Definition der einzelnen Member möglichst simpel und
übersichtlich geschehen sollte, so dass dies bei jeder Erweiterung oder
neuen Klasse nicht in einer endloser Tipparbeit ausartet und die
entsprechenden Constraints/Eigenschaften sofort ersichtlich sind.
Viel mehr werden die einzelnen Klassen viele tausend Male instanziert,
so dass hier schon ein gewisser unnötiger Overhead zusammenkommt.
Der Ansatz mit den Templates war auch mein erster Gedanke, allerdings
stößt man hier auch recht schnell an Grenzen, so dass weitere
Workarounds notwendig sind. Ein Beispiel nanntest du ja mit den
Gleitkomma-Parametern bereits.
Auch Strings (z.B. die Attribut-Namen) lassen sich nicht direkt als
Template-Parameter übergeben, da diese "external linkage" benötigen, was
den Code auch wieder weiter "zerfleddert".
Sollte es hier jedoch eine elegante Lösung geben, wäre ich diesem Ansatz
nicht abgeneigt.
@Rolf Magnus
Dieser Ansatz gefällt mir auch sehr gut, zumal sich dies so gestalten
ließe, dass das bisherige Interface nicht verändert werden müsste.
Ich werde dies einmal an einer konkreten Implementierung testen und mich
dann noch einmal melden.
Viele Grüße,
Peter
Auf die Gefahr hin, mich unbeliebt zu machen: Wenn Du dort mit
Meta-Daten über Attributen arbeiten musst und nicht ganz sicher bist,
wie es nun für alle Zeit aussehen soll: Modelliere die Klassen in UML
und generiere die Implementierungen der Daten- und Meta-Daten Klassen
aus dieser Darstellung. Dann kannst du noch viel rumprobieren und bist
auch in der Zukunft nicht festgelegt auf Lösungen, die ohne viel
Schreibarbeit funktionieren.