Klassendesign - Hierarchie Ebenen

Status
Nicht offen für weitere Antworten.

The_S

Top Contributor
Hi,

ich benötige eure Hilfe bei der Entwicklung eines Klassendesigns. Wie würdet ihr das angehen? Ich möchte eine Hierarchische Anordnung von Objekten ein und derselben Klasse. Diese Hierarchie kann n-Ebenen haben. Dabei sollen die Objekte anderen Objekten als untergeordnet zugewiesen werden. Z. B. so:

+Root

--+Eins
----+Eins-Eins
----+Eins-Zwei
------+Eins-Zwei-Eins
----+Eins-Drei

--+Zwei

--+Drei
----+Drei-Eins

Kommen wir zu meinem eigentlichen Problem! Die Klasse hat natürlich verschiedene Variablen. Wird jetzt eine Variable im Objekt verändert, soll sich (je nachdem welche Variable verändert wurde) sich diese Änderung auch auf alle untergeordneten Objekte auswirken. Sollten neue Objekte untergeordnet werden, sollen diese Objekte ebenfalls die Variablen zugeordnet bekommen. Gleichzeitig muss überprüft werden, ob die Zuweisung einer Variable bezüglich des übergeordneten Objekts gültig ist (z. B. die Variable "Datum" darf nicht höher als dieselbe Variable des übergeordneten Objekts sein). Wird ein Objekt einem anderen Objekt neu unterwiesen, so muss auch hier überprüft werden, ob evtl. ungültige Werte bereits gesetzt wurden und diese dann ggf. abändern. Und zuguter letzt muss ein untergeordnetes Objekt auch an dem übergeordnetem Objekt bestimmte Variabeln ändern können, ohne dass sich das auf die restlichen untergeordneten Objekte des Owners auswirkt.

Wie würdet ihr das Designen?

Schonmal danke fürs lesen ;) .
 
S

SlaterB

Gast
ich würde da ganz sanft anfangen mit Operationen

setX() für alle Attribute, auch für interne Änderungen,
die die entsprechenden Unterobjekte ändert,
+
getX() sowieso
+
addChild(Typ child)

-------

eine entscheidene Frage ist, ob du ein kleine Framework haben willst,
oder einzeln Änderungen aufrufst,

beim letzteren müsste z.B. in setDatum manuell setDatum der Kinderelemente gerufen werden
(den Elementen der Kinderliste speziell für dieses Attribut, alles einzeln),
bei anderen Attributen entsprechend andere Aufrufe,

-----

beim Framework solltest du die vorhanden Attribute wohl in einem Objekt-Array oder sonst wie allgemein vorhalten,
so dass jedes set wie setDatum() nur noch in einen anderen Aufruf wie
setAttribute(ATTRIBUTE_DATUM_INDEX,newDatum);
umgewandelt wird,
und allgemeine Operationen wie setAttribute() die ganze Arbeit übernehmen,
egal um welches Attribut es sich gerade handelt,
 

The_S

Top Contributor
So, erstmal danke für deine Antwort :D .

SlaterB hat gesagt.:
ich würde da ganz sanft anfangen mit Operationen

setX() für alle Attribute, auch für interne Änderungen,
die die entsprechenden Unterobjekte ändert,
+
getX() sowieso
+
addChild(Typ child)

So hab ich auch zuerst angefangen, wird aber ab ner bestimmten Anzahl von Regeln und Variablen recht unübersichtlich. Ich denk, ich werde nochmal komplett neu Anfangen und schauen wie ich das Ganze optimieren kann.

SlaterB hat gesagt.:
eine entscheidene Frage ist, ob du ein kleine Framework haben willst,
oder einzeln Änderungen aufrufst

Ein Framework wäre zwar ne super Sache, aber ist imho mehr Aufwand als Ertrag.

Ich werde jetzt wie gesagt nochmal die Klasse "ganz sanft" ;) aufbauen und schauen ob es diesmal besser hinhaut. Falls nicht meld ich mich nochmal!
 

Yzebär

Bekanntes Mitglied
Ich würde das durch die Anwendung des Observer-Patterns lösen und zwar in beide Richtungen (untergeordnet<-->übergeordnet). Ein untergeordnetes Objekt meldet sich bei einem übergeordneten Objekt an. Bei Attributsänderungen im übergeordneten Objekt wird das untergeordnete Objekt benachrichtigt und die Attribute werden aktualisiert, das untergeordnete Objekt benachrichtigt alle ihm untergeordneten Objekte....

Umgekehrt meldet sich das übergeordnete Objekt auch beim untergeordneten Objekt an und wird bei bestimmten Änderungen im untergeordneten Objekt benachrichtigt und die Attribute werde auch aktualisiert, es wird aber kein weiteres übergeordnetes Objekt benachrichtigt.

Anmeldung erfolgt beim Verknüpfen der Objekte und die Abmeldung, wenn die Verknüpfung wieder gelöst wird.
 

The_S

Top Contributor
Hab ich mir auch überlegt, aber da ich von einem Objekt aus auf das jeweils unter bzw. übergeordnete Element mitsamt allen Methoden zugreifen muss, würde das imho sehr schnell Spagetthi Code erzeugen. Hab mich jetzt erstmal dazu entschieden das Ganze mit Referenzen zu lösen (setOwner, getOwned, ...).

Aber so wie ich mich kenne, werd ich das sowieso noch 10000 mal umschmeißen ;) .

Aber Danke!
 

Yzebär

Bekanntes Mitglied
Wenn du die Methoden sowieso direkt aufrufst, warum diese nicht in einem Interface deklarieren und damit bist du ja schon fast wieder beim Observer-Pattern... und mit einem setOwner(Object ref) machst du eh nichts anderes als ein register(Object ref). Das Ganze (mit dem Interface) macht natürlich nur Sinn, wenn es sich auch um eine erweiterbare Softwarearchitektur handeln soll. Wenn du weißt, daß du nur Objekte von einer einzigen Klasse verwenden wirst, brauchst du natürlich kein Interface. Das Observer-Pattern (wenn auch in abgewandelter Form), mußt du sowieso anwenden, oder wie aktualisierst du mehrere untergeordnete Objekte?

Übrigens, wenn ich viele Attribute habe, die ich setzen und auslesen möchte, benutze ich nicht für jedes Attribut eine get/set-Methode, sondern verwende eine HashMap. So kann ich später neue Attribute hinzufügen oder weglassen(zB über Konfig-Datei parametrierbar), ohne die Klasse ändern zu müssen und habe eine set(key, value)- und eine get(key)-Methode.
 

The_S

Top Contributor
Yzebär hat gesagt.:
Das Ganze (mit dem Interface) macht natürlich nur Sinn, wenn es sich auch um eine erweiterbare Softwarearchitektur handeln soll. Wenn du weißt, daß du nur Objekte von einer einzigen Klasse verwenden wirst, brauchst du natürlich kein Interface.

Das ist der Punkt ;) .

Yzebär hat gesagt.:
Das Observer-Pattern (wenn auch in abgewandelter Form), mußt du sowieso anwenden, oder wie aktualisierst du mehrere untergeordnete Objekte?

Über die Referenz auf die anderen Objekte. Ich bezweifle, dass man das mit dem Observer-Pattern gleichsetzen kann ...

Yzebär hat gesagt.:
Übrigens, wenn ich viele Attribute habe, die ich setzen und auslesen möchte, benutze ich nicht für jedes Attribut eine get/set-Methode, sondern verwende eine HashMap. So kann ich später neue Attribute hinzufügen oder weglassen(zB über Konfig-Datei parametrierbar), ohne die Klasse ändern zu müssen und habe eine set(key, value)- und eine get(key)-Methode.

Is ja nicht alles nur von einem Datentyp. Ich verwende viele unterschiedliche Datentypen. Und unterschiedliche Datentypen in eine HashMap schmeißen hab ich mir Seit Java 5 abgewöhnt ;) . Ist aber natürlich Ansichtssache :) .
 

byte

Top Contributor
Wegen der Objekthierarchie wäre vielleicht die Anwendung des Composite Musters hilfreich. Ich würde dann noch versuchen, die Schnittstelle der Attribute zu vereinheitlichen (abstrakte Oberklasse/ Interface). Dann kannst Du recht elegant traversieren bzw. die Attribute ändern (for each child : change attribute value).
 

The_S

Top Contributor
Ansich nicht schlecht die Idee, aber lässt sich leider nicht auf alle Attribute anwenden, da es sich zu ca. einem Drittel um primitive Datentypen handelt. Aber danke für den Hinweis, evtl. fällt mir ja doch noch was ein, wie ich das elegant einbauen kann. Die Idee gefällt mir nämlich soweit :) .
 

Yzebär

Bekanntes Mitglied
Die Ähnlichkeit mit dem Observer habe ich dahingehend gemeint, daß du durch eine Liste von Objekten iterieren mußt und Methoden der Objekte aufrufst. Und dies nicht zu einem x-beliebigen Zeitpunkt, sondern nur, wenn es eine Änderung gab, die diese Objekte auch betreffen soll. Dies entspricht vom Charakter dem notify-update-Mechanismus. Wie gesagt, ein "echtes" Observer-Pattern lohnt nur, wenn es verschiedene Objekttypen gibt (dann braucht man ja auch das Interface).

Ich verwende für die HashMap nur Strings. Ich muß dann zwar an der Stelle, wo ich mit den Werten rechnen will, konvertieren, aber das ist mir die Flexibilität wert. Dies ist natürlich keine universelle Lösung, es kommt zB sehr darauf an, was für Datentypen man hat.

PS: Ich will dir hier nichts aufschwatzen, ich sehe das eher als eine Art Brainstorming.
 

The_S

Top Contributor
Yzebär hat gesagt.:
Die Ähnlichkeit mit dem Observer habe ich dahingehend gemeint, daß du durch eine Liste von Objekten iterieren mußt und Methoden der Objekte aufrufst. Und dies nicht zu einem x-beliebigen Zeitpunkt, sondern nur, wenn es eine Änderung gab, die diese Objekte auch betreffen soll. Dies entspricht vom Charakter dem notify-update-Mechanismus. Wie gesagt, ein "echtes" Observer-Pattern lohnt nur, wenn es verschiedene Objekttypen gibt (dann braucht man ja auch das Interface).

Ja, in der Hinsicht hast du natürlich recht :) .

Yzebär hat gesagt.:
PS: Ich will dir hier nichts aufschwatzen, ich sehe das eher als eine Art Brainstorming.

Das sehe ich auch so. Ich hab ja hier gefragt und bin für jede Antwort dankbar. Inwiefern diese dann auf meine Anwendung anwendbar ist muss ich entscheiden. Ihr kennt sie ja nicht ;) . Ich lass mir auch jeden Lösungsvorschlag durch den Kopf gehen. Weil umsetzen ist kein Problem, ist nur die Frage wie es am Schönsten ist :D . Und bis ich mir das alles mal überlegt habe, braucht es natürlich auch Zeit und n paar Versuche, aber das bin ich ja mittlerweile von mir schon gewohnt :p .
 

byte

Top Contributor
Hobbit_Im_Blutrausch hat gesagt.:
Ansich nicht schlecht die Idee, aber lässt sich leider nicht auf alle Attribute anwenden, da es sich zu ca. einem Drittel um primitive Datentypen handelt. Aber danke für den Hinweis, evtl. fällt mir ja doch noch was ein, wie ich das elegant einbauen kann. Die Idee gefällt mir nämlich soweit :) .

Ich meinte, dass Du die primitiven Datentypen in einem Objekt kapselt, statt sie direkt als primitives Feld zu führen. Dort kannst Du dann entsprechende Methoden zum Setzen der Werte deklarieren, aber z.b. auch Deine Prüfung auf Validität.
 

Yzebär

Bekanntes Mitglied
Genau und dann könntest du die Attribute in einer HashMap<String><Interface> verwalten, dann sieht deine Objektklasse schön schlank aus... na gut... du hast ca. 45623Mio. Klassen für die Attribute, aber irgendwo muß es ja einen Haken geben.
 

The_S

Top Contributor
Keine schlechte Idee, gefällt mir gut (mal ausgenommen der Arbeit, die ich mit dem erstellen der Klassen habe ;) ). Ich glaub das werde ich so umsetzen. Danke!
 

Wildcard

Top Contributor
Ich würde eine drüber nachdenken das mit EMF generieren zu lassen.
Du hast Container Klassen (Knoten) die ein Containment Feature auf ihren Kindern (Blätter) setzen.
Damit sind die Objekte gegenseitig bekannt.
Die update Sache regelst du dann über die vorhandene Adapter Schnittstelle, und schön bist du mit sehr wenig Code aus der Sache raus.
 

The_S

Top Contributor
Hab noch nichts mit EMF gemacht und bis gerade eben auch ncoh nicht mal gewusst was das ist (Wikipedia sei dank ;) ). Aber ich werds mir mal anschauen. Danke!
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben