Singleton hier sinnvol?

System.exit(0)

Aktives Mitglied
Hallo,

ich habe eine klasse SpielSteuerung, die sämtliche für die Steuerung des Spieles wichtigen Variablen enthält. Insbesondere die ganzen Sprites, auf die dauernd zugegriffen werden muss.
Natürlich enthält diese Klasse auch alle notwendigen Methoden.

Mit zunehmender Komplexität des Spiels ist die Klasse ziemlich lang geworden. Insbesondere da in den wichtigsten Methoden vielen ifs und switches vorkommen.

Jetzt kam mir die Idee, die notwendigen Variablen in der Klasse zu belassen und in Instanzen einer Sub_SpielSteuerung-Klasse SpielStuerung als Singleton Referenz instanziert zu haben.

Ziel ist, dass in der Mutter-SpielStuerung nur noch die Variablen zu finden sind.
Die Methoden beschränken sich hier auf die Entscheidung durch ifs udn switches, welche Unternmethode aufzurufen ist. Die genaue Implementierung der Methode - abhängig vom Spielgeschehen - geschieht dann in der Sub_Spielsteuerung.

Beispiel, wie es dann aussehen würde. drawMe ist momentan ziemlich lang - und damit unübersichtlich.

Java:
cluss Sub_SpielSteuerung()
{
     private SpielSteuerung Parent;
     
     public Sub_SpielSteuerung(SpielSteurung parent)
     {
           this.Parent = parent.getInsanceOf();
     }

    (...)

}

class Sub_Spiel extends Sub_SpielSteuerung()
{ 
(...)
}

class Sub_GameOver extends Sub_SpielSteuerung()
{ 
(...)
}

class SpielSteuerung 

private Sub_Spiel Spiel;
private Sub_GameOver GameOver;
private boolean gameisover;
(...)

public void drawMe (Graphics G)

if (gamesisover)
{
      GameOver.drawMe(G);
}
else
{
     Spiel.drawMe(G);
}
(...)

Wäre das hier ein angebrachtes Vorgehen oder sollte ich eine andere Lösung suchen.

Gruß

System.exit(0)
 

sambalmueslie

Bekanntes Mitglied
Hm wenn etwas komplex und unübersichtlich wird, dann bietet sich immer der Gedanke an, einmal über eine entsprechende Aufteilung nachzudenken.

Ich würde versuchen unterschiedliche Klassen für die einzelnen Aufgaben zu definieren.
Vielleicht sogar, dass du eine State-Machine (Zustandsautomat) baust und dort dann die vielen If/Switch dinge durch unterschiedliche Zustandsobjekte abfängst.

Für die eigentlichen Daten würde sich ein "Model" denke ich anbieten :)

Gruß Oli
 

System.exit(0)

Aktives Mitglied
Hallo,

die Aufteilung wollte ich ja über die Unterklassen machen.
Wäre denn meine SpielStuerung nicht schon fast der state-Automat?

Jede dieser Sub_Steurungen würde einen definierten Zustand des Spiels abdecken. Um einen einfachen, aber sichereren Zugriff zu gewähren, würden aber alle Spieldaten (sprich die Sprites und ein paar Umgebugnsvariablen) in der Singleton-Klasse enthalten sein.
Die Parent-Steurklasse würde dann je nach Zustand die Sub-Steurerungsklasse erzeugen, verwenden und bei einer Zustandsänderung wieder vernichten.

Das Problem, das ich habe und hier lösen will, ist eigentlich hauptsächlich die Übergabe der Sprites, die ja in der (Ur) Steuerung gespeichert sind.

Die Sub_Steuerungen sollen lediglich das Ausführen der jeweils notwendigen Logiken und das Zeichnen des jeweils zu Zeichnenden sicher stellen.

Die einzelnen Logiken für Bewegungen und Zeichnen ist in den Sprites definiert und für die Collisions, das Erzeugen und Löschen neuer Sprites gibt es ebenfalls eine Klasse, die das übernimmt.

Gruß

System.exit(0)
 

sambalmueslie

Bekanntes Mitglied
Hm Singleton geht natürlcih, aber das ist immer sehr global. Lieber den Objekten direkt das benötigte zuweisen, dann sieht man auch bei der verwendung schnell die Abhängigkeiten.

Du kannst ja für deine Zustandsobjekte eine abstrakte Oberklasse erzeugen,
die dann eine Referenz auf das Daten-Objekt hat und somit hat jeder Zustand, Zugriff auf die Daten, ganz ohne Singleton :)

Gruß Oli
 

Marco13

Top Contributor
Ja, das Singleton. Die Datenhure, wo jeder mal drüberrutschen darf. Und wenn man was hat, wo man nicht weiß, wo es hin soll, packt man's in's Singleton, weil das ja praktischerweise immer und überall verfügbar ist. Der Effekt, dass so eine Klasse immer länger wird, und immer mehr Dinge in sich vereint, die eigentlich nichts miteinander zu tun haben, ist wohl nicht ungewöhnlich.

Wenn ich das richtig verstanden habe, war die Hauptintention für das Singleton ja das zur Verfügung stellen der Sprites. Warum die Sprites nicht an einer dedizierten Stelle geladen und den Klassen übergeben werden, die sie brauchen, weiß ich nicht. Wenn es NUR darum geht, also das Singleton im Sinne eines ... "abstrahierten File Systems", oder eines "Sprite Repositories" verwendet wird, könnte es sogar OK sein. Aber die Spielsteuerung an sich sollte man wohl nicht in ein Singleton packen.
 
S

Spacerat

Gast
Hmm... GRUNDSATZDISKUSSION :D
Masterkontrollstruktur (Service) -> Singleton
Spielsteuerung -> Masterkontrollstruktur
...Ich würde schon für Singleton plädieren.
 

sambalmueslie

Bekanntes Mitglied
Jippi.. ich liebe Grundsatzdiskussionen :D

ne spaß :)

aber ich finde, er kann in dem Fall auch gut ohne Singleton auskommen :)

Ätsch .... ;)

Gruß Oli
 

System.exit(0)

Aktives Mitglied
@Marco13

Genau darum geht es: Die Sprites als "abstrahieretes FielSystem" (schöner Begriff).
Die Klassen, denen das Singleton übergeben würde, würden nur auf die Sprites und deren Methoden zugreifen.
Selbst das Hinzufügen oder Löschen von Sprites würde immer noch in den dafür vorgesehen Klassen passieren.

Gruß

System.exit(0)
 
M

maki

Gast
???:L Ein Singleton, das noch irgendwo hin übergeben wird?

Also, dann mal ganz rudimentär: Wer sollte wann wo aus welchem Grund etwas machen wollen (oder können, oder dürfen), was mit
Spielsteuerung.getInstance(). ...
anfängt?
Gut erkannt Marco13, ein Singleton macht hier überhaupt keinen Sinn, sowas ist eine Mischform aus Resource Lookup(Singleton) & Dependency Injection, mit den Nachteilen von beiden:
Java:
     public Sub_SpielSteuerung(SpielSteurung parent)
     {
           this.Parent = parent.getInsanceOf();
     }
Dazu wird da noch das Law of Demeter verletzt...

Entweder richtiges Singleton mit klassischem Zugriff oder DI, beides für sich alleine ist immer noch besser als diese Mischform...
 

System.exit(0)

Aktives Mitglied
Ich habe jetzt angefangen, mein Spiel auf Singleton umzustellen.
Dabei ist die Klasse GameData das Singleton (Instanz heißt myData) und die Methoden get...() liefern die Referenz auf die Sprite-Liste.

Aber ich habe festgestelllt, dass ich mich dabei komisch fühle, weil ich letztlich alle wichtigen Variablen dadurch indirekt auf public setze.

Spricht eigentlich, abgesehen bom Tipp-Aufwand, etwas gegen solche Methoden, bei denen zig Parameter übergeben werden (manchmal auch mehr als benötigt, da die Methoden von einer abstrakten Klasse kommen, um sicher zu stellen, dass alles, was man benötigen könnte, auch da ist)?

Ich finde, dass es vielleicht den Code nicht ganz so übersichtlich macht, solch lange Methodenaufrufe, aber irgendwie fühlt es isch besse an.

Was sagt ihr?

Gruß

System.exit(0)

ohne Sinleton:
Java:
 public void DrawMe(SpielSteuerung Parent, Rakete myShip, 
                    MyListClass<MySprite> myStars, MyListClass<MySprite> myBullits, 
                    MyListClass<MySprite> myAliens, MyListClass<MySprite> myAlienBullits, 
                    MyListClass<MySprite> myExplosions, int fps, Graphics G, FontMetrics FM) 
{
       G.clearRect(0, 0, myMain.width, myMain.height);

        G.setColor(Color.white);
        // Sterne zeichnen
        if (myStars.size() > 0)
        {
        for (MySprite S : myStars)
            S.drawMe(G);
        }
(...)
}

mit Singleton:
Java:
 public void DrawMe(SpielSteuerung Parent, int fps, Graphics G, FontMetrics FM) 
{
       G.clearRect(0, 0, myMain.width, myMain.height);

        G.setColor(Color.white);
        // Sterne zeichnen
        if (myData.getmyStars().size() > 0)
        {
        for (MySprite S : myData.getmyStars())
            S.drawMe(G);
        }
(...)
}
 
S

Spacerat

Gast
Solange, gesetzt den Fall es gibt mehrere Methoden, diese dieselben Objekttypen als Parameter erwarten, kann man diese Parameter zugunsten der Übersicht auch in einer "Struktur" (Sprich einer Klasse, die nur Eigenschaften und keine Methoden hat) bündeln. Ferner könnte man auch innerhalb der Methode z.B. die FontMetrics immer wieder neu aus Graphics holen.
Zusätzlich könnte man die diversen Sprite-Listen in einer Enumeration zusammenfassen (Collection<MySprite> implementieren, zu überschreibende Methoden einfach an interne Collection delegieren). Dieser Enumeration kann man dann DrawMe als statische Methode hinzufügen. Die interne Collection könnte man ebenfalls statisch machen. Hätte den Vorteil, das man nur eine benötigt, aber dann müssten die Zugriffe (insbesondere die Iteration darüber) unbedingt synchronisiert werden, was ohnehin jetzt schon ratsam ist (bitte nicht so pauschal sehen wie es klingt).
 

Marco13

Top Contributor
Ich habe jetzt angefangen, mein Spiel auf Singleton umzustellen
....
ohne Sinleton:
Java:
 public void DrawMe(SpielSteuerung Parent, Rakete myShip, 
                    MyListClass<MySprite> myStars, MyListClass<MySprite> myBullits, 
                    MyListClass<MySprite> myAliens, MyListClass<MySprite> myAlienBullits, 
                    MyListClass<MySprite> myExplosions, int fps, Graphics G, FontMetrics FM) 
{
...

Und in welcher Klasse steht das? Könnten die Listen nicht ohnehin lokal in dieser Klasse liegen? Oder (wie schon gesagt wurde) EINE Instanz einer Klasse übergeben werden, die diese Sachen zusammenfasst?
 

System.exit(0)

Aktives Mitglied
Hallo,

Danke für die die Hinweise.
Mir ist jetzt nich ganz klar, wie die Klasse
(Sprich einer Klasse, die nur Eigenschaften und keine Methoden hat)
aussehen müsste. Wahrscheinlich ist es noch zu früh, ich steh gerade auf dem Schlauch.

Der Zugriff ist jetzt schon synchronisiert, oder besser gesagt, linear gestaltet. Der keyListener ist gegen den Zugriff auf eine gerade benutzte Liste über eine boolean abgesichert.

Gruß

System.exit(0)
 
S

Spacerat

Gast
Ungefähr so:
Java:
class MyStruct {
  public SpielSteuerung parent;
  public Rakete myShip;
  public MyLisstClass<MySprite>
    myStars,
    myBullits,
    myAliens,
    myAlienBullits,
    myExplosions;
  public int fps;
}
Graphics und FontMetrics hab' ich mal weggelassen, weil es alles andere als sinnvoll ist, diese dort mit einzubringen.
Das die Member nun alle [c]public[/c] sind, ist auch nicht das beste Design. Besser wäre entweder [c]public final[/c], Objekte müssten dann einmal per Konstruktor übergeben werden, oder [c]private[/c], dann müssten die Member per Getter und Setter beeinflusst werden. In der Regel kommt man sehr schnell drauf, dass man die Listen doch besser (wie Marco13 bereits sagte) mit in die Klasse übernimmt, die [c]DrawMe[/c] enthält.
Im übrigen: Ein boolean bietet äusserst wenig Schutz vor RaceConditions. Obendrein ist es meistens als eine Art Busy-Waiting einzustufen (implementierungsabhängig).
 
B

bygones

Gast
Ja, das Singleton. Die Datenhure, wo jeder mal drüberrutschen darf. Und wenn man was hat, wo man nicht weiß, wo es hin soll, packt man's in's Singleton, weil das ja praktischerweise immer und überall verfügbar ist. Der Effekt, dass so eine Klasse immer länger wird, und immer mehr Dinge in sich vereint, die eigentlich nichts miteinander zu tun haben, ist wohl nicht ungewöhnlich.
wie geil... fast Signaturenwertvoll :)
 

System.exit(0)

Aktives Mitglied
Hallo,

ich will meine Variablen eben icht public haben. Deswegen war ich so verwundert über die Klasse ohne Methoden.

Mit private Variablen im Singleton arbeite ich schon.

Java:
class MyStruct {
  private SpielSteuerung parent;
  private Rakete myShip;
  private MyLisstClass<MySprite> myStars

  public MyStuct (SpielSteuerung Parent)
  { this.parent = Parent;
     myShip = new myShip();
    myStars = new MyListClass <MySprite> ("myStars"); 
  public int fps;
  }

  public MyListClass <MySprite> getmyStars()
  { 
     return myStars;
  }

  public Rakete getmyShip()
  {
     return myShip;
  }
 usw.
}

Einer Setter Methode bedarf es nicht, da die Referenz übergeben wird und jede Manipulation der Liste in der Referenzadresse geschieht.

Somit liefert z. B. folgender Befehl in einer anderen Klasse das gewünschte Ergebnis, dass der Liste myStars ein Stern zugefügt wird.

Java:
(...)
    // myData wäre hier die in der Spielsteuerung erzeugt einzige Instanz von myStruct
   myData.getmyStars().add(new Stern( ... ));
    // oder festlegen der Position von myShip
   myData.getmyShip().setCoord(100, 100);

usw.

System.exit(0)
 

Marco13

Top Contributor
Spacereat's Vorschlag von "MyStruct" war wohl nur sinnbildlich - natürlich würde man da get/set Methoden für die Zugriffe verwenden.

Aber mal was ganz anderes: Was (zum ...) ist eine "MyLisstClass"? (Abgesehen davon, dass dieses "My"-Präfix IMHO :autsch: ist) Sollte das nicht einfach eine List sein?
 
S

Spacerat

Gast
Öhm... [c]MyLisstClass[/c] ist 'n Druckfehler... :oops: sollte eigentlich [c]MyListClass[/c] heissen, wie vom TS vorgeschlagen...
[c]Structs[/c] in Java? ...jibbet doch jar nich... ist natürlich nur sinnbildlich gemeint. Aber ich bin immer noch der Meinung, dass die Felder auch ruhig [c]public final[/c] sein dürfen, wenn sie sich zur Laufzeit, abgesehen vom Inhalt, ohnehin nicht ändern (ein Indiz dafür ist, das es nur Getter geben soll). Was sie hingegen nicht sein dürfen, ist [c]public[/c] only, weil dann könnte jeder ungeprüft die Daten verändern.
 

System.exit(0)

Aktives Mitglied
Die LIsten werden ständig geändert. Es kommen MySprites dazu, es werden welche gelöscht.
Und man benötigt auch dann nur getter, wenn man die Listen ändern will.

Probiert es aus, so wie es oben beschrieben ist. Die get-Methoden übergeben Referenzen, somit kann ich den Inhalt, der sich hinter dem Pointer befindet, ändern.

MyListClass ist abgeleitet von ArrayList, damit ich beim Aufruf des Konstruktors ein paar debug-Infos speichern kann (u.a. den String, der beim Konstruktor übergeben wird).

Gruß

System.exit(0)
 
S

Spacerat

Gast
Probiert es aus, so wie es oben beschrieben ist. Die get-Methoden übergeben Referenzen, somit kann ich den Inhalt, der sich hinter dem Pointer befindet, ändern.
Heisst das, dass die Listen innerhalb der Klasse ständig neu instanziert werden? Und das die Klassen die sich eine Instanz der aktuellen Liste holen diese dann überall verändern bzw. drüber iterieren können? Fatalerweise vllt. noch in verschiedenen Threads (z.B. EDT bzw. KeyListener) unsynchronisiert und unkopiert? Dann aber ganz schnell weg vom ewigen neu instanzieren.
Java:
class SomeClass
{
  private final List<Sprite> sprites = new ArrayList<Sprite>();

  public void addSprite(Sprite s)
  {
    synchronized(sprites) {
      sprites.add(s);
    }
  }

  public void removeSprite(Sprite s)
  {
    synchronized(sprites) {
      sprites.remove(s);
    }
  }

  public Sprite getSprite(int index)
  {
    synchronized(sprites) {
      sprites.get(index);
    }
  }

  public List<Sprite> getSprites()
  {
    synchronized(sprites) {
      return new ArrayList<Sprite>(sprites);
    }
  }
}
Über die List, welche man durch [c]getSprites()[/c] bekommt, kann an jeder Stelle im Programm gefahrlos iteriert werden. Werden während der Iteration Sprites hinzugefügt oder entfernt, wird dieses erst beim nächsten Durchlauf registriert. [c]someclass.addSprite(sprite);[/c] durfte auch um einiges bequemer sein als [c]someclass.getSprites().add(sprite);[/c]. Während ersteres von überall aus dem Programm aufgerufen werden kann, bekommt die Hauptliste beim 2. das hinzufügen von Sprites kaum (faktisch sogar gar nicht) mit.
@Edit: Nochmal zum Thema... Ich würd' sagen, das wir uns vom Singleton inzwischen doch in gänze verabschiedet haben. Für deine Klasse Spielsteuerung ist mir grad' noch folgendes eingefallen... http://www.java-forum.org/allgemein...m-design-stichwort-oo-pattern.html#post567052
 
Zuletzt bearbeitet von einem Moderator:
Ähnliche Java Themen
  Titel Forum Antworten Datum
EinNickname9 Best Practice Singleton und Singleton mit Instanz zu anderer Klasse -Pattern Allgemeine Java-Themen 30
Neoline Klassen Singleton Klasse buchmanager Allgemeine Java-Themen 19
J Singleton Allgemeine Java-Themen 5
Z deserialize singleton Allgemeine Java-Themen 9
A Singleton threadsafe Allgemeine Java-Themen 8
S Singleton Instanz löschen Allgemeine Java-Themen 5
A Datei als Object einlesen und das Object als Singleton instance setzen. Allgemeine Java-Themen 13
T ActionListener und Singleton Allgemeine Java-Themen 15
S Singleton Entwurfsmuster Allgemeine Java-Themen 20
T So eine Art Singleton-Factory? Allgemeine Java-Themen 3
S Singleton-Klasse und ThreadLocal-Klasse von abstrakter Klasse ableiten? Allgemeine Java-Themen 2
T Zugriff auf Singleton verkürzen - Namespaces?? Allgemeine Java-Themen 20
B Volatile Frage: Reicht es nur den Singleton als volatile zu deklarieren? Allgemeine Java-Themen 4
Iron Monkey Singleton mit Parameter Allgemeine Java-Themen 14
G Singleton Frage: Allgemeine Java-Themen 17
M Singleton und Vererbung? Allgemeine Java-Themen 45
R Wo initilisiere ich eine Liste in einem Singleton? Allgemeine Java-Themen 2
M Java Garbage Collector Frage (Singleton Pattern) Allgemeine Java-Themen 13
B Generisches Singleton implementieren Allgemeine Java-Themen 12
H Singleton und MultiThreading [erledigt] Allgemeine Java-Themen 3
S Singleton Pattern mit Generics Allgemeine Java-Themen 4
P SingleTon Allgemeine Java-Themen 5
M zwei Threads - ein singleton-Objekt Allgemeine Java-Themen 3
RaoulDuke Agent als Singleton Thread Allgemeine Java-Themen 7
S singleton vs. static Allgemeine Java-Themen 7
P Singleton vs static Allgemeine Java-Themen 19
K Singleton vererben Allgemeine Java-Themen 15
E Singleton vererben Allgemeine Java-Themen 10
E Frage zu Singleton Allgemeine Java-Themen 22
D Design Pattern: Singleton Allgemeine Java-Themen 4
K Sequenzdiagramm für Singleton-Muster Allgemeine Java-Themen 5
Zrebna SonarLint: Warum kein Null-Referencing-CodeSmell-Hint hier? Allgemeine Java-Themen 23
Calli11 Was muss ich hier in die Main schreiben, damit das Programm ausgeführt wird? Allgemeine Java-Themen 4
C Was passt hier nicht bei der Calendar-Class Allgemeine Java-Themen 2
jhCDtGVjcZGcfzug Klassen Was genau passiert hier? Kann mir das jemand bitte Zeile für Zeile erklären? Allgemeine Java-Themen 1
berserkerdq2 Kann keine Labels erstellen, was ist hier syntaktisch falsch Allgemeine Java-Themen 5
N Ist Selenium hier das richtige Werkzeug? Allgemeine Java-Themen 1
Zrebna Wieviele Testfälle muss man hier schreiben? (Software Engineering) Allgemeine Java-Themen 13
A Ist ein enum hier richtig? Enum toString() Methode. Allgemeine Java-Themen 1
Drachenbauer warum bekomme ich hier eine NullPointerException Allgemeine Java-Themen 6
X Wie mache ich hier eine Rekursion rein ? Allgemeine Java-Themen 7
S Eigenschaften (hier Verknüpfung) eines Files lesen Allgemeine Java-Themen 2
J Einrückungstool mit Farblicher hervorhebung wie hier? Allgemeine Java-Themen 3
V VisualVM Was erkennt ihr hier? Allgemeine Java-Themen 9
E Queue: Wie kann hier ein null-Pointer Exception auftreten?! Allgemeine Java-Themen 11
R Was ist hier falsch? Abfragen Allgemeine Java-Themen 3
X Wer kann mir das hier erklären? Programm frisst RAM! Allgemeine Java-Themen 11
E Wieso returnt das hier 1? Allgemeine Java-Themen 3
W Wieso funktioniert dieser Code hier? Allgemeine Java-Themen 6
G Warum kommt hier NullPointerException? Allgemeine Java-Themen 3
F Threading oder kein Threading - das ist hier die Frage. Allgemeine Java-Themen 23
D Timer oder Thread, das ist hier die Frage Allgemeine Java-Themen 3
egrath Anonyme Methode - warum hier kein Compilerfehler Allgemeine Java-Themen 2
F Gutes Threads Tutorial hier aber trotzdem eine Frage Allgemeine Java-Themen 7
M Spring oder nicht, das ist hier die Frage Allgemeine Java-Themen 3
S Was ist hier falsch? Allgemeine Java-Themen 16
G wer muss hier wen aufrufen? Allgemeine Java-Themen 7
M Kann man hier noch was rausholen? Allgemeine Java-Themen 16
A Was passiert hier? Allgemeine Java-Themen 13
I Ist JNI hier richtig? Allgemeine Java-Themen 8
B Gibts sogar hier Allgemeine Java-Themen 3

Ähnliche Java Themen

Neue Themen


Oben