Erben leicht gemacht (o. Sinnvolle Vererbung)



  • Hallo allerseits,

    ich stehe vor einem Problem, dessen (sinnvolle) Lösung mir einfach nicht einfallen will. Ich versuch euch mal mein Problem zu erläutern.

    Nehmen wir an ich habe eine Klasse ClientTab und eine Klasse UserTab. In diesen Klassen befinden sich verschieden QLabels, QLineEdits und diverse andere Objekte zur Verwaltung der jeweiligen Daten. Unter anderem existiert in beiden Klassen eine GroupBox für die Kontaktdaten. In der GroupBox der ClientTab-Klasse sind folgende Lable- und LineEdit-Paare enthalten: Name, Email, Telefon, Straße, Hausnummer, PLZ und Ort. In der GroupBox der UserTab-Klasse sind an sich die selben Elemente enthalten, jedoch kommen noch weiter Felder hinzu. Nun stellt sich mir die große Frage. Wie vererbe ich am besten.
    Mein derzeiges Desing sieht so aus:
    Ich hab eine Basisklasse namens CustomerManagementTab. Dort sind die Objekt enthalten die in beiden Widgets vorkommen. Diese werden im Konstruktor erstellt. Erstelle ich nun eine Unterklasse, ruft diese erst den Konstruktor der Basisklasse auf und fügt dann seine jeweiligen Objekt in das in der Basisklasse als protected deklarierten Layout der GroupBox ein. Dieses Design bringt aber folgende Probleme mit sich.
    1. Wenn ich ein Objekte an einer Stelle weiter oben im Layout einfüge, funktioniert die Tabulator-Reihenfolge nicht. Die Funktion setTabOrder zu verwenden würde nicht funktionieren, da ich von der Unterklasse nich auf die Objekte der Basisklasse zugreifen kann.
    2. Ich kann keine weiter Unterklasse von CustomerManagementTab ableiten in der zwar die oben genannten Felder existieren aber anders angeordnet sind.

    Das brachte mich zu der Überlegung, die Klassen dahingehend zu verändern, dass die Klasse CustomerManagementTab zwar die jeweiligen Objekte protected deklariert aber dieser erst in der Klasse, welche das eigentlich Widget anzeigt initialisiert werden. Das hieße aber, dass ich in jeder abgeleiteten Klasse immer die jeweiligen Objekte erstellen müsse.

    So ich hoffe ihr versteht mein Problem und könnt mir sagen, was die bessere Lösung ist.

    Zuguterletzt möchte ich noch anmerken dass die oben beschriebene Struktur nur ein Ausschnitt ist.

    Ich freu mich schon auf eure antworten

    Gruß
    Hoschek


  • Mod

    Ich würde auf Ableitung verzichten, und es als hat ein Beziehung implementieren.

    Soweit ich das sehe, haben beide Klassen eine art Address Daten. Diese ließen sich zu einer Klasse Address machen.

    Für den View hieße dies, das sich einfach in die Tabklassen ein AddressPanel einfügt. Welches die jeweiligen Addressdaten beinhaltet.
    Erweiterungen könnte man über ein Flag z.b. in der Panelklasse dynamisch erzeugen lassen.



  • Erstmal danke für deine Antwort.

    Du meinst also dass ich eine Klasse Adress erstelle in der die jeweiligen Felder erstellt werden. Diese Klasse inkludiere ich dann in die jeweilige Klasse. Angenommen in der einen Tab Klasse soll im Adressfeld ein Feld Anrede eingebunden werden, in der anderen aber nicht, dann löse ich dies mittels eines Flags in der Adress-Klasse (Beispielsweise Salutation = true oder so)

    Meintest du das so? Das Problem wäre dass ich genau von diesem Design weg wollte. Also nicht davon dass ich eine Klasse für die Adressdaten erstelle sondern dass ich etwaige hinzukommende Felder mittels Flags verwalte. So sahen mein klassen früher aus und diese ewige if-else geschichte machte das ganz zu unübersichtlich. Gerade wenn nicht nur ein sondern mehrere unterschiedliche Felder je nach art des Tabs dynamisch erzeugt werden müssen...


  • Mod

    Ja, ist schon klar, das das nicht der Königsweg ist.

    Aber in Adressdaten gehören imho ja auch nicht die Anrede rein.
    Sondern Straße, Hausnr, PLZ, Stadt. Nichts personenbezogenes.
    Und notralls muss man halt 2 Klassen erstellen, oder es halt eben in einer Klasse erweitern (Ableitung z.B.).
    Und meines erachtens solltest du nicht Tabs von einander ableiten, eine gemeinsame Basisklasse ist ok, aber imho sollte die GUI Erstellung dann immer von der Childklasse ausgehen.
    Die Basisklasse kann natürlich entsprechende Methoden bieten, wie z.b. wxPanel* CreateAddressPanel(wxWindow* parent, int id);

    phlox



  • Ja da hast du recht dass sowas nicht da rein gehört aber leider muss ich es so machen.

    Also ich beschreib dir nochmal kurz wie das ganze aussieht.

    Ich habe ein Tab ClientTab. In diesen sind Informationen zum Kunden, z.B. einer Firma dargestellt. Dort enthalten ist auch das Feld für die Kontaktdaten mit Name, Email, Telefon, Straße, PLZ und Ort.

    Der nächste Tab ist UserTab. Dieser enthält Daten zu einer Person des Kunden. Das Feld Kontakt ist dahingehend anders, dass neben Namen, Email, Telefon, Straße, PLZ und Ort auch die Felder Passwort, Anrede und Sprache enthalten sind.

    Hinzu kommt noch ein dritter Tab den man als eine Abart des UserTabs sehen kann. In diesen Tab kommt zu dem Kontaktfeld das Feld Status hinzu. Ich weiß, der Aufbau ist ganz und gar nicht logisch jedoch wird es so gewünscht und daran ändern kann ich leider auch nichts.

    Es wäre also sinnvoller die Objekte in den Basisklassen zu deklarieren, die intialisierung bzw. die Erstellung des Widgets in der Childklasse vorzunehmen. Ok das klingt auch ganz logisch aber ich versteh wie du das meinst, dass ich dann eine Methode der Basisklasse aufrufen soll?

    Gruß
    Hoschek


  • Mod

    Du könntest in der Basisklasse entsprechende Methoden für die Erzeugung der einheitlichen GUI Elemente zur Verfügung stellen.
    Diese würden dann im Childklassen Konstruktor aufgerufen. So könntest du z.B. auch erreichen das die gleichen Controls je nach Klasse verschiedene Parents haben.


Anmelden zum Antworten