JavaRush /Java-Blog /Random-DE /Muster und Singleton – für alle, die ihnen zum ersten Mal...

Muster und Singleton – für alle, die ihnen zum ersten Mal begegnet sind

Veröffentlicht in der Gruppe Random-DE
Dieser Artikel richtet sich an diejenigen, die zum ersten Mal mit dem Konzept der Muster in Berührung gekommen sind, davon gehört Singletonoder es irgendwie geschafft haben, aber immer noch nichts verstanden haben. Willkommen! JavaRush-Schüler begegnen Mustern zum ersten Mal auf Stufe 15, als die Obergrenze unerwartet dazu auffordert, ein Muster Singletonmit einer verzögerten Implementierung zu „reparieren“ und zu implementieren. Studierende, die zum ersten Mal davon hören, Singletonhaben sofort eine Reihe von Fragen: Was ist ein Muster, warum wird es benötigt, was für ein Muster ist es Singletonund schließlich, was für eine verzögerte Implementierung ist das? Beginnen wir mit der Beantwortung in der Reihenfolge: Muster und Singleton – für alle, die ihnen zum ersten Mal begegnet sind – 1

Was ist überhaupt ein Muster?

Zum besseren Verständnis halte ich es für sinnvoll, diese Frage aus der Geschichte zu beantworten. Unter den Programmierern gibt es so berühmte vier Autoren: Erich Gamma, Richard Helm, Ralph Johnson und John Vlissides, die eine interessante Idee hatten.
Muster und Singleton – für alle, die ihnen zum ersten Mal begegnet sind – 2
Sie stellten fest, dass sie beim Schreiben von Programmen oft ungefähr die gleichen Probleme lösen und Code vom gleichen Typ in der Struktur schreiben mussten. Daher beschlossen sie, typische Muster, die häufig in der objektorientierten Programmierung verwendet werden, in Form von Mustern zu beschreiben. Das Buch erschien 1995 unter dem Titel „Techniques of Object-Oriented Design. Designmuster" . Der Titel des Buches erwies sich als zu lang und es wurde einfach als „ Das Buch der Viererbande“ bekannt . In der ersten Auflage wurden 23 Muster veröffentlicht, danach wurden Dutzende weitere entdeckt. Um also die Frage in diesem Absatz „Was sind Muster?“ zu beantworten , fassen wir es in wenigen Worten zusammen:
Ein Muster ist eine standardisierte Lösung für ein häufiges Problem.
Und Singletondas ist nur eines dieser Muster.

Warum brauchen wir Muster (Designmuster)

Sie können programmieren, ohne Muster zu kennen; Sie können dies einfach überprüfen, indem Sie sich darüber im Klaren sind, dass Sie bis zum 15. Level in JavaRush Hunderte von Miniprogrammen geschrieben haben, ohne etwas über deren Existenz zu wissen. Dies legt nahe, dass es sich bei einem Muster um eine Art Werkzeug handelt, dessen Vorhandensein einen Meister vom Amateur unterscheidet:
Muster und Singleton – für alle, die ihnen zum ersten Mal begegnet sind – 3
Die Muster beschreiben, wie man eines der typischen Probleme richtig löst. Dadurch sparen Sie Zeit, wenn Sie die Muster kennen. Eine Analogie kann zu Algorithmen gezogen werden. Man kann sich zum Beispiel einen eigenen Sortieralgorithmus mit Blackjack und Zahlen ausdenken und viel Zeit damit verbringen, oder man nutzt einen, der bereits vor längerer Zeit beschrieben wurde, und setzt ihn um. Dasselbe gilt auch für Muster. Außerdem wird der Code durch die Verwendung von Mustern standardisierter, und wenn Sie die richtigen Muster verwenden, ist die Wahrscheinlichkeit geringer, dass Sie Fehler machen, da diese in diesem Muster bereits vorhergesehen und beseitigt wurden. Darüber hinaus ermöglicht die Kenntnis von Mustern den Programmierern, sich gegenseitig besser zu verstehen. Es reicht aus, einfach den Namen der Vorlage zu nennen, anstatt zu versuchen, Ihren Programmierkollegen zu erklären, was Sie von ihnen erwarten. Zusammenfassend lässt sich sagen, dass Designmuster helfen:
  • das Rad nicht neu erfinden, sondern Standardlösungen nutzen;
  • Code standardisieren;
  • Terminologie standardisieren;
Abschließend stellen wir fest, dass sich die gesamte Mustervielfalt in drei große Gruppen einteilen lässt:
Muster und Singleton – für alle, die ihnen zum ersten Mal begegnet sind – 4

Endlich ein Singleton-Muster

Singletonbezieht sich auf generative Muster . Die wörtliche Übersetzung lautet „Einzelgänger“. Dieses Muster stellt sicher, dass eine Klasse nur ein Objekt (eine Instanz der Klasse) hat und dass ein globaler Zugriffspunkt für dieses Objekt bereitgestellt wird. Aus der Beschreibung sollte klar hervorgehen, dass dieses Muster in zwei Fällen verwendet werden sollte:
  1. wenn in Ihrem Programm nicht mehr als ein Objekt einer Klasse erstellt werden soll. In einem Computerspiel gibt es beispielsweise eine Klasse „Charakter“, und diese Klasse sollte nur ein Objekt haben, das den Charakter selbst beschreibt.

  2. wenn Sie einen globalen Zugriffspunkt auf ein Klassenobjekt bereitstellen müssen. Mit anderen Worten: Sie müssen sicherstellen, dass das Objekt von einer beliebigen Stelle im Programm aufgerufen wird. Und leider reicht es dafür nicht aus, einfach eine globale Variable zu erstellen, da diese nicht schreibgeschützt ist und jeder den Wert dieser Variablen ändern kann und der globale Zugriffspunkt auf das Objekt verloren geht. Diese Eigenschaften Singletonwerden beispielsweise benötigt, wenn Sie ein Objekt einer Klasse haben, das mit einer Datenbank arbeitet, und Sie möchten, dass die Datenbank von verschiedenen Teilen des Programms aus zugänglich sein soll. Und Singletones stellt sicher, dass kein anderer Code die zuvor erstellte Instanz der Klasse ersetzt hat.
Diese beiden Probleme werden dadurch gelöst Singleton: Es darf nur ein Objekt im Programm vorhanden sein und es muss globaler Zugriff darauf bestehen. Im Beispiel auf Level 15 fordert die Kappe dazu auf, dieses Muster für die folgende Aufgabe zu implementieren (hier ist seine Beschreibung):
Muster und Singleton – für alle, die ihnen zum ersten Mal begegnet sind – 5
Nach sorgfältiger Lektüre der Bedingung wird klar, warum Singletonhier genau (Single) benötigt wird. Schließlich fordert Sie das Programm auf, ein Objekt jeder Klasse zu erstellen: Sun, Moon, Earth. Und es ist logisch anzunehmen, dass jede Klasse im Programm nicht mehr als eine Sonne/einen Mond/eine Erde erschaffen sollte, sonst wäre es absurd, es sei denn natürlich, Sie schreiben Ihre eigene Version von Star Wars. Feature der Java- ImplementierungSingleton in drei Schritten Das Singleton-Verhalten in Java kann nicht mit einem regulären Konstruktor implementiert werden, da der Konstruktor immer ein neues Objekt zurückgibt. Daher laufen alle Implementierungen von Singleton'a darauf hinaus, den Konstruktor zu verbergen und eine öffentliche statische Methode zu erstellen, die die Existenz eines einzelnen Objekts kontrolliert und alle neu erscheinenden Objekte „zerstört“. Wenn Singleton'a aufgerufen wird, muss es entweder ein neues Objekt erstellen (sofern es nicht bereits im Programm vorhanden ist) oder ein bereits erstelltes Objekt zurückgeben. Gehen Sie dazu wie folgt vor: #1. – Sie müssen der Klasse, die ein einzelnes Objekt enthält, ein privates statisches Feld hinzufügen:
public class LazyInitializedSingleton {
	private static LazyInitializedSingleton instance; //#1
}
#2. – Machen Sie den Klassenkonstruktor (Standardkonstruktor) privat (so dass der Zugriff darauf außerhalb der Klasse gesperrt ist und keine neuen Objekte zurückgegeben werden können):
public class LazyInitializedSingleton {
	private static LazyInitializedSingleton instance;
private LazyInitializedSingleton(){} // #2
}
#3 . – Deklarieren Sie eine statische Erstellungsmethode, die zum Abrufen des Singletons verwendet wird:
public class LazyInitializedSingleton {
    private static LazyInitializedSingleton instance;
        private LazyInitializedSingleton(){}
        public static LazyInitializedSingleton getInstance(){ // #3
        if(instance == null){		//wenn das Objekt noch nicht erstellt wurde
            instance = new LazyInitializedSingleton();	//Erstelle ein neues Objekt
        }
        return instance;		// das zuvor erstellte Objekt zurückgeben
    }
}
Das obige Beispiel ist etwas umständlich, da wir den Konstruktor einfach ausblenden und anstelle des Standardkonstruktors unsere eigene Methode bereitstellen. Da dieser Artikel darauf abzielt, JavaRush-Studenten den ersten Kontakt mit diesem Muster (und Mustern im Allgemeinen) zu ermöglichen, wird hier nicht auf die Implementierungsfunktionen komplexerer Singletons eingegangen. Wir weisen lediglich darauf hin, dass je nach Komplexität des Programms eine detailliertere Verfeinerung dieses Musters erforderlich sein kann. Beispielsweise können in einer Multithread-Umgebung (siehe Thema Threads) mehrere verschiedene Threads gleichzeitig die Getter-Methode von Singleton aufrufen, und der oben beschriebene Code funktioniert nicht mehr, da jeder einzelne Thread mehrere Instanzen der Klasse erstellen kann auf einmal. Daher gibt es noch verschiedene Ansätze zur Erstellung korrekter Thread-sicherer Singletons. Aber das ist eine andere Geschichte =) Und schließlich. Was ist die verzögerte Initialisierung, nach der die Obergrenze verlangt ? Die verzögerte Initialisierung wird auch als verzögerte Initialisierung bezeichnet. Hierbei handelt es sich um eine Programmiertechnik, bei der ein ressourcenintensiver Vorgang (und das Erstellen eines Objekts ist ein ressourcenintensiver Vorgang) bei Bedarf und nicht im Voraus ausgeführt wird. Das ist im Grunde das, was in unserem Code Singleton„a“ passiert. Mit anderen Worten: Unser Objekt wird in dem Moment erstellt, in dem darauf zugegriffen wird, und nicht im Voraus. Es sollte nicht davon ausgegangen werden, dass das Konzept der verzögerten Initialisierung irgendwie eng mit Singleton„om“ verbunden ist. Die verzögerte Initialisierung wird auch in anderen generativen Entwurfsmustern verwendet, beispielsweise in der Proxy- und Factory-Methode, aber das ist eine andere Geschichte =) Bei der Erstellung des Artikels wurden die folgenden Quellen verwendet:
  1. Best Practices für Java-Singleton-Entwurfsmuster mit Beispielen
  2. Designmuster
  3. Korrekter Singleton in Java
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION