Wie vermeidet man Singletons beim Erstellen eines OOP-State-Machine-Designs?

8

Ich versuche gerade, mich selbst programmieren zu lernen. Ich begann den gleichen Weg, von dem ich sicher bin, dass die meisten Leute anfangen; kleine, unordentliche Apps und Spiele erstellen, die auf nicht so einfache Weise einfache Dinge tun. Vor kurzem habe ich versucht, den nächsten Schritt zu machen, indem ich ein etwas komplexeres Spiel schreibe, das OOP-Design verwendet, um besseren, modularen Code zu schreiben!

Das Hauptproblem, das ich hatte, ist das Design meiner Haupt-StateManager (FSM) -Klasse (um zwischen den Bildschirmzuständen intro / menu / game / etc zu wechseln). Ich habe hoch und niedrig geschaut, und ich habe nur zwei Methoden gesehen, sie zu entwerfen:

  • Verwenden Sie eine switch / case-Anweisung + eine enum, um zwischen den Zuständen zu wechseln.

  • Erstellen Sie eine Singleton-FSM-Klasse, die Pushing / Popping-Zustände zu / von einem Vektor verarbeitet.

Nun, mein Problem ist, dass die Switch-Case-Anweisung sehr repetitiv und klobig ist, und es funktioniert irgendwie gegen mein Ziel, dieses Projekt zu benutzen, um mich selbst OOP beizubringen.

Mein zweites und größeres Problem ist der Singleton-Vorschlag.

Wie ich schon sagte, ich versuche, mich selbst zu unterrichten, und ich muss noch eine Menge lernen, wenn es um das Programmieren geht, besonders im Bereich der OOP- und Designmuster und all dieser Dinge. Ich bin auf ein Problem gestoßen, wo für ALLE "Singletons bösen" Threads und Diskussionen, die ich finde, ich genauso viele Tutorials und Referenzen finde, wo Leute Singles in ihrem Code verwenden, um "Engine" -Klassen und FSMs zu machen . Es ist eine sehr konsistente gemischte Nachricht.

Ich nehme an, ich verstehe einfach nicht warum ... Selbst wenn Sie nur ein einzelnes Objekt einer Klasse haben wollen / wollen, warum ist es dann notwendig / vorteilhaft, den Konstruktor privat zu machen und ein Singleton zu erstellen? Ich habe viel darüber gelesen, wie Singletons schlecht sind, wie sie im Wesentlichen global sind, wie sie Multi-Threading behindern, und wie viele Programmierer sie für überstrapaziert halten oder für einfach schlechtes Design ... Dennoch sehe ich ein Beispiel nach dem anderen von Leuten, die sie benutzen, und sehr wenige Gegenbeispiele, die alternative Methoden zeigen.

Könnte nicht die gleiche Art von Sache mit nur einer regulären Klasse getan werden? Was ist der Zweck, die Erstellung von Instanzen explizit zu beschränken? Ich habe nur negative Dinge über Singletons gehört, aber die Leute scheinen sie ständig zu benutzen ... Fehle ich etwas über Singletons und OOP?

Ist die Verwendung von Singletons nur ein Trend, oder ist es nur ein Trend, wenn Leute Singles "böse" nennen? Wie komme ich da um ..? Gibt es nicht irgendwas zwischen dem Switch / Case FSM und dem Singleton FSM? Könnte jemand das Zustandssystem seines Programms nicht genau so entwerfen, ohne irgendwelche Klassen Singletons zu bilden? Würde das etwas ändern? [ verwirrt ]

    
MrKatSwordfish 09.08.2012, 11:13
quelle

3 Antworten

6
  

Könnte nicht die gleiche Art von Sache mit nur einer regulären Klasse getan werden? Was ist der Zweck, die Erstellung von Instanzen explizit zu beschränken? Ich habe nur negative Dinge über Singletons gehört, aber die Leute scheinen sie ständig zu benutzen ... Vermisse ich etwas über Singletons und OOP überhaupt?

Nein, ich glaube, Sie sind auf dem richtigen Weg: Es gibt absolut keinen Grund, die Erstellung von zwei Instanzen zu verhindern. Das Universum wird deswegen nicht implodieren.

Es ist eine völlig unnötige Einschränkung. Da Sie diese Einschränkung manuell codieren müssen, ist es ziemlich albern, sie überhaupt zu haben (wenn Sie Code schreiben mussten, heben es, wäre das eine andere Sache).

Ich nehme an, dass es seltsame und seltene Situationen geben kann, in denen das Universum implodiert, wenn eine zweite Instanz erstellt wird, aber das klingt ziemlich weit hergeholt. In jedem Fall rechtfertigt es nicht die Verbreitung von Singletons im gesamten Internet.

Ich kann nicht wirklich erklären, warum die Leute sie ständig benutzen, ohne die Denkfähigkeiten dieser Leute zu beleidigen, also werde ich das nicht tun.

  

Könnte jemand das Zustandssystem seines Programms nicht auf die gleiche Art und Weise gestalten, ohne einen seiner Klassen Singletons zu machen? Würde das etwas ändern?

Das einzige, was es ändert, ist, dass Sie, indem Sie es zu einem Singleton machen, verhindern, dass Sie wegwerfbare Instanzen für Komponententests erstellen. Alles andere funktioniert genauso.

    
R. Martinho Fernandes 09.08.2012, 11:19
quelle
2

Wie so oft gibt es keine einfache Antwort. In C ++, der Singleton-Muster verwaltet auch die Reihenfolge der Initialisierungsprobleme, die sind wichtig, wenn es in den Konstruktoren von statischen Objekten verwendet werden soll. Und es gibt bestimmte Arten von Objekten, bei denen nur mehrere Instanzen möglich sind ein Programmierfehler sein; wenn Sie sie verhindern können, warum nicht.

Auf der anderen Seite habe ich große Schwierigkeiten, mir einen Fall vorzustellen wo eine Klasse StateManager sollte ein Singleton sein. Es ist in keiner Weise Verwalten einer einzigartigen Ressource oder irgendeiner Meta-Funktionalität (z.B. Logging), die von Natur aus einzigartig sein müssen. Und ich kann mir nicht vorstellen Es wird entweder in den Konstruktoren von statischen Objekten verwendet.

Eine Aussage wie "Singletons sind schlecht" ist sehr irreführend; für einige Dinge, sie sind die am besten geeignete Lösung. Aber nur weil sie sind nicht schlecht im absoluten bedeutet nicht, dass sie angemessen sind überall. Sie lösen ein bestimmtes, sehr begrenztes Problem. Wenn du Um dieses Problem zu lösen, ist nicht mit einem Singleton schlecht. Aber (wie es ist true für fast alles), wenn es unpassend ist schlecht.

    
James Kanze 09.08.2012 12:09
quelle
1

Ich verstehe nicht, warum die FSM-Klasse ein Singleton sein sollte. Es gibt viele reale FSM-Systeme, in denen es keine Singletons gibt, verdammt, es gibt einige, wo die Zustandsinstanzen erzeugt und zerstört werden, wenn der SM die Zustände durchläuft, und where ist die Zustandsmaschine selbst ein Zustand, der die einfache Zusammensetzbarkeit hierarchischer Zustandsautomaten ermöglicht.

In einer komplexen Anwendung haben Sie mehrere Zustandsautomaten, von denen einige ein- und ausgehen. Diejenigen, die zum Beispiel Client-Server-Interaktionen handhaben, haben notwendigerweise mehrere Instanzen, die mit Clients kommen und gehen. Einige andere können davon profitieren, mehrere hierarchische Zustandsmaschinen zu bilden, von denen einige an vielen Stellen wiederverwendet werden können. Daher ist die Idee, dass Sie eine Zustandsmaschine als Singleton Klasse haben, für mich albern. Sie können beispielsweise eine -Instanz einer bestimmten Statemachine in einer Singleton-Anwendungsklasse haben, die Ihre Anwendung kapselt, aber das ist weit entfernt von einer Singleton-Klassenstatusmaschine.

Um einen guten Überblick über verschiedene Techniken zur Implementierung von Zustandsautomaten zu erhalten, einschließlich Kontraste zwischen flachen FSMs und hierarchischen Zustandsautomaten (HSMs), sollten Sie sich Miro Sameks PSICC2 Buch. Er hat viele frei herunterladbare Artikel , in denen gängige Techniken erklärt werden.

Eine vernünftige C ++ - Implementierung einer hierarchischen Zustandsmaschine, die für die Benutzeroberfläche geeignet ist, ist im Status verfügbar Maschinenrahmen in Qt .

    
Kuba Ober 09.08.2012 11:50
quelle

Tags und Links