Parameter soll Referenz vom zu erstellenden Objekt erhalten

Rudolf

Bekanntes Mitglied
Hi,

folgender Code ist nicht fehlerfrei umzusetzen:

Java:
Player playerA = new PlayerA(new ReadyState(playerA), game, mediator);
Player playerB = new PlayerB(new ReadyState(playerB), game, mediator);

Gibt es eine elegante Lösung statt mit einem setter für dieses Vorhaben?
 
N

nillehammer

Gast
Zirkuläre Abhängigkeiten zweier Klassen untereinander "riechen" etwas fragwürdig. Aber egal. Eine Variante wäre, ReadyState nicht als Konstruktorparameter für Player zu nutzen, sondern erst im Konstruktor von Player zu erzeugen, etwa so:
Java:
public class Player {

  private final ReadyState readyState;

  public Player(..die anderen Parameter...) {
    ... alles andere...
    // als letze Zeile des Konstruktors
    this.readyState = new ReadyState(this);
  }
}
 

Rudolf

Bekanntes Mitglied
Warum riecht das? Kannst du das begründen?

Entweder ich setze das StrategyPattern so um, dass die Methoden der Strategieklassen die Referenz vom Player kriegen oder ich nutze den Konstruktor einer Strategieklasse um die Referenz zu setzen. Ansonsten wäre deine Variante auch denkbar.
 
N

nillehammer

Gast
"Eine Klasse, die für ihre Erzeugung eine Referenz auf die Instanz einer anderen Klasse braucht, die wiederum für ihre Erzeugung eine Referenz auf eine Instanz der ersten braucht." Klingt schon beim Lesen merkwürdig, oder?

Ohne die Klassen im Detail zu kennen, liegt die Vermutung nahe, dass diese beiden Klassen (oder Teilaspekte dieser Klassen) eigentlich zusammen gehören.

Wenn Du möchtest, poste die beiden Klassen. Dann kann man sehen, ob ich gänzlich daneben liege.
 
N

nillehammer

Gast
Entweder ich setze das StrategyPattern so um, dass die Methoden der Strategieklassen die Referenz vom Player kriegen
Das halte ich für sinnvoller. Die Strategy ist meinem Verständnis nach sowas wie ein Service, der möglichst keinen inneren Status haben sollte. Und der Player sollte als (dumme) Datenhaltungsklasse überhaupt nichts von irgendwelchen Strategies wissen. Mag aber im konkreten Anwendungsfall natürlich immer Ausnahmen geben oder ich interpretiere die Klassennamen nicht korrekt...
 

Rudolf

Bekanntes Mitglied
Die Strategy hat auch keinen inneren Zustand, sondern nur eine Referenz vom Objekt, der einen Zustand hat (oder verstehe ich dich falsch). Also um es nochmal klar zu machen.

Mit

Entweder ich setze das StrategyPattern so um, dass die Methoden der Strategieklassen die Referenz vom Player kriegen

meine ich wirklich nur, dass die Objekte, die das StrategyPattern umsetzen, also die einzelnen Strategieklassen, eine Feldreferenz vom Objekt haben, auf die das StrategyPattern angesetzt ist. Oder man übergibt bei den einzelnen Methodenaurufen immer eine Referenz der Kontextklasse mit. Mit Kontextklasse meine ich http://upload.wikimedia.org/wikipedia/commons/0/08/StrategyPatternClassDiagram.svg

An dieser Stelle eine andere interessante Frage. In wie fern macht die Umsetzung des StrategyPatterns mit enum Sinn? Welche Vor und Nachteile hat man. Der einzige Nachteil, der mir bekannt ist, dass enumMethoden nicht überschrieben werden können, da sie static sind. Bei nicht enum Klassen kann man das und ist daher flexibler. Dafür muss man an einigen Stellen equals überschreiben, um Zustände miteinander zu vergleichen, das oft statt einem interface eine abstrakte klasse erzwingt, die equals ala return getClass.equals(obj.getClass()) benötigt.

Bzw wann wäre es vorteilhaft beim StrategyPattern Klassen zu erweitern (also Methoden zu überschreiben usw).
 
Zuletzt bearbeitet:
N

nillehammer

Gast
Die Strategy hat auch keinen inneren Zustand, sondern nur eine Referenz vom Objekt, der einen Zustand hat (oder verstehe ich dich falsch). Also um es nochmal klar zu machen.

Mit
Entweder ich setze das StrategyPattern so um, dass die Methoden der Strategieklassen die Referenz vom Player kriegen
meine ich wirklich nur, dass die Objekte, die das StrategyPattern umsetzen, also die einzelnen Strategieklassen, eine Feldreferenz vom Objekt haben, auf die das StrategyPattern angesetzt ist. Oder man übergibt bei den einzelnen Methodenaurufen immer eine Referenz der Kontextklasse mit. Mit Kontextklasse meine ich http://upload.wikimedia.org/wikipedi...assDiagram.svg
Aso, der Player ist bei Dir der Kontext. Bin ich nicht drauf gekommen, weil Player sich für mich sehr nach Datenklasse anhört, die in der execute?-Methode manipuliert werden soll und deswegen besser dort als Parameter übergeben werden sollte. Wenn Player aber der Kontext ist, wäre die Frage andersrum zu stellen: "Wieso muss der Kontext die Strategy kennen?
An dieser Stelle eine andere interessante Frage. In wie fern macht die Umsetzung des StrategyPatterns mit enum Sinn? Welche Vor und Nachteile hat man. Der einzige Nachteil, der mir bekannt ist, dass enumMethoden nicht überschrieben werden können, da sie static sind. Bei nicht enum Klassen kann man das und ist daher flexibler. Dafür muss man an einigen Stellen equals überschreiben, um Zustände miteinander zu vergleichen, das oft statt einem interface eine abstrakte klasse erzwingt, die equals ala return getClass.equals(obj.getClass()) benötigt.
Wenn du ein Interface definierst bzw. es schon eins gibt und dann die enums dieses Interface implementieren lässt, kann man das schon machen (find ich sogar sehr sinnvoll). Ich verwende das bspw. sehr gerne für Comparator- oder Filter-Implementierungen. Wobei die natürlich keinen Context benötigen.

Bei enums ist die Verwendung von Instanzvariablen allerdings ggf. problematisch, weil jede enum-Konstante ja ein Singleton ist. Das wäre vielleicht auch ein von Dir nachgefragter Nachteil.
 
Zuletzt bearbeitet von einem Moderator:

Ähnliche Java Themen


Oben