2017-01-28 1 views
1

Ich implementierte die Singleton Muster in meinem Spiel auf instance Funktionen und Variablen wie sie static zugreifen. Alles gut und gut, ich kann es bequem benutzen. Nach meinem Verständnis hat jedoch alles einen Preis und diese Benutzerfreundlichkeit muss irgendeine Art von Nachteil haben. Frage ist, ist es eine Menge Aufwand, um zum Beispiel GameManager.instance.someOtherClass.someVariable häufig zu verwenden? Im Allgemeinen, wie leistungsfähig ist die Singleton?Singleton Muster Leistungsnachteile

Antwort

2

Ein wichtiger Teil beim Entwurf großer Softwaresysteme ist die Minimierung der Kopplung zwischen Komponenten und Klassen. Dies kann durch die Verkapselung der Implementierung verschiedener Komponenten erfolgen. Je mehr Komponenten voneinander wissen, desto höher ist die Abhängigkeit zwischen ihnen.

Die Verwendung des Singleton-Patterns bedeutet, dass es an eine Implementierungsklasse gekoppelt wird (nicht an eine Schnittstelle oder an eine Abstraktion). Es wäre besser, wenn jede Komponente, die den GameManager verwendet, stattdessen ein GameManagerInterface verwendet, so dass die Implementierung leicht geändert oder erweitert werden kann. Es ist schwierig, die Abhängigkeit von der konkreten Singleton-Klasse zu verbergen, denn irgendwo muss man die statische Methode aufrufen.

... 
IGameManager iGameManager = GameManager.getInstance(); 
... 

das Muster Singleton verwenden wie das ist ...:

GameManager.instance.someOtherClass.someVariable  

... ist nie eine gute Idee. Dies würde die aufrufende Klasse mit der Implementierung jeder der aufgerufenen Klassen verbinden. Es ist am besten, nur mit Ihren direkten Nachbarn zu kommunizieren, wie im "Gesetz von Demeter" (a.ka.a "Tell Do not Ask" oder "Sprechen Sie nicht mit Fremden").

Vielleicht ist es für Sie an der Zeit, über den Zweck des Singleton-Pattern nachzudenken: Das Singleton-Pattern wird verwendet, um sicherzustellen, dass es nur eine Instanz einer Klasse gibt. Nichts mehr.

Die Verwendung der statischen "getInstance" -Methode überall in Ihrem Code führt zu versteckten Abhängigkeiten, wie bereits erwähnt. Sie verwenden das Singleton-Muster als Ersatz für eine globale Variable. Dies macht Ihr System fragil, da jedes Bit Ihres Codes von der Implementierung der Singleton-Klasse abhängig ist. Wenn Sie diese Klasse ändern, kann Ihr gesamtes System zum Absturz gebracht werden.

+0

Obwohl es kein riesiges Programm ist, ist es in der Tat am besten, so früh wie möglich zu lernen. Also sage ich, ich habe eine Klasse namens 'Charakter'. Und diese Zeichenklasse möchte ein Detail wissen, das im Singleton gespeichert ist, sagen wir 'levelUpBoundary' für wie hoch der Charakter sein kann. Im Moment würde ich das von 'GameManager.instance.levelUpBoundary' bekommen. Was du sagst ist, dass ich eine Variable in meinem 'Charakter'-Skript wie folgt erstellen soll: ' IGameManager iGameManager = GameManager.getInstance(); 'genau wie du gesagt hast? Wenn ja, wie genau? –

+0

Erstens: es gibt eine Sache, die Kohäsion genannt wird, was bedeutet, dass Methoden nah an den Daten sein sollten, an denen sie arbeiten ... Sie sollten über die Struktur nachdenken. Ist es wirklich notwendig, dass der GameManager etwas über die levelUpBoundaries eines Charakters weiß? Meiner Meinung nach ist es ein Implementierungsdetail der Klasse Character. Zweitens: Wie bereits erwähnt, ist das Singleton-Muster kein Ersatz für eine globale Variable, was Sie hier verwenden. Sie sollten den GameManager als normales Objekt in der Hauptmethode erstellen und als Abstraktion in die anderen Objekte einfügen. – Janis

0

Im Allgemeinen sollte Java in der Lage sein, häufig verwendete Zugriffe so zu optimieren. Ich denke nicht, dass der Performance-Hit wichtig sein sollte, bis Sie wirklich ein fertiges Spiel haben und die Performance-Optimierung starten, während Sie den Einfluss messen.

Das ernstere Problem könnte auftreten, wenn Sie immer mehr als eine Instanz von etwas verwenden möchten, dann müssen Sie Ihre Architektur ändern. Ich bin im Allgemeinen kein Freund von Singletons und würde sie nur verwenden, wenn ich 100% sicher bin, dass ich niemals eine zweite Instanz einer Klasse brauchen könnte.

+1

Das ist eine Tatsache genau dort. Obwohl für mich, wenn ich einen Singleton benutze, ist es nur ein Singleton im gesamten Spiel/App, nicht mehr. Ich versuche, etwas nicht zu viel zu verwenden und zerbrich meine Sachen zu Komponenten für die einfache Erweiterbarkeit und so weiter. –

+0

In diesem Fall gehen Sie einfach mit ihm. Ich bin mir zu 99% sicher, dass dies niemals einen messbaren Einfluss auf Ihre Leistung haben wird. Das kommt normalerweise von Grafik-Operationen und Netzwerk-Verkehr, vielleicht einige schwere Algorithmen wie Terrain-Generierung, etc. Definitiv nicht vom Zugriff auf Singletons. – Silverclaw

2

Es gibt keinen Leistungsnachteil, wenn Sie häufig das Singleton-Muster verwenden. Verwenden Sie es aus dieser Sicht, wie oft Sie mögen. Aber wenn Sie diese Variable oft brauchen, sollten Sie über ein Redesign nachdenken. Verwenden Sie den Singleton nicht, wenn Sie eine globale Variable benötigen. Es gibt nur einen Grund für das Singleton: "Es ist nicht erlaubt, mehr als eine Instanz einer Klasse zu haben."

Seien Sie also vorsichtig mit diesem Muster. Janis erklärte dieses Problem sehr gut in seinem answer.

0

Die Antwort ist einfach, messen Singleton und nicht Sigleton Ansatz.In Singleton wird ein neues Objekt auf dem Heap erstellt, sobald ein Nicht-Singleton-Objekt bei jedem Aufruf erstellt wird.