Singleton einfache Instanz -Design -Musteranalyse
Vorwort
Heute werde ich Ihnen eine umfassende Zusammenfassung des am häufigsten verwendeten Designmusters in der Android -Entwicklung - Singleton -Modus - geben.
In Bezug auf die Einführung in Designmuster können Sie lesen, was ich zuvor geschrieben habe: 1 Minute, um "Designmuster" vollständig zu verstehen,
Inhaltsverzeichnis
1.
1.1 Welche Probleme werden gelöst?
Wie bereits erwähnt, entworfene Muster = eine Lösung für eine bestimmte Art von spezifischem Problem. Welches Problem ist also das Singleton -Muster ?
Bedeutung: Singleton = eine Instanz;
Problem gelöst: Reduzieren Sie die Kopplung zwischen Objekten
Lösung: Singleton -Muster, dh implementiert, dass eine Klasse nur ein instanziiertes Objekt hat und einen globalen Zugriffspunkt liefert
1.2 Instanzeinführung
Als nächstes verwende ich eine Instanz, um das Singleton -Muster einzuführen
Hintergrund: Xiaangeng hat eine Kunststofffabrik, aber es gibt nur ein Lagerhaus.
Zweck: Ich möchte Code verwenden, um die Lagerverwaltung zu implementieren
Aktuelle Praktiken: Lagern und Arbeiter einrichten
Unter ihnen die Menge in der Lagerklasse = die Menge der Waren; Arbeiter haben die Handhabungsmethoden Movein (int i) und Moveout (int i).
Probleme: Durch Tests wurde festgestellt, dass jedes Mal, wenn ein Arbeiter bewegt wird, ein neues Lagerhaus gebaut wird, dh die Ware werden nicht im selben Lagerhaus platziert. Was ist los? (Siehe Code unten)
paket scut.designmodel.singletonpattern; // Lagerhause Klassenklasse CODOUSHOUSE {private int mantity = 100; public void setquantity (int mantity) {this.quantity = mantity; } public int getQuantity () {return quantity; }} // Human Class Carrier {Public Storehouse Mstorehouse; Public Carrier (Lagerhaus Lagerhaus) {Mstorehouse = Lagerhaus; } // Waren in das Warehouse public void movein (int i) {mstorehouse.setQuantity (mstorehouse.getQuantity ()+i); } // Aus dem Warehouse public void moveout (int i) {mstorehouse.setQuantity (mstorehouse.getQuantity ()-i); }} // Arbeiterbearbeitungstest public class SinglePattern {public static void main (String [] args) {Lagerhaus mstorehouse1 = new Speicherhaus (); Lagerhaus mstorehouse2 = new Lagerhaus (); Carrier Carrier1 = neuer Träger (Mstorehouse1); Carrier Carrier2 = neuer Träger (Mstorehouse2); System.out.println ("Sind die beiden gleich?"); if (mstorehouse1.equals (mstorehouse2)) {// Verwenden Sie hier gleich anstelle des == Symbols, da das Symbol == nur die Adressen der beiden Objekte system.out.println ("ist das gleiche"); } else {System.out.println ("ist nicht gleich"); } // Nachdem der Porter die Ware bewegt hat, melden Sie die Warenmenge im Lagerträger1.Movein (30); System.out.println ("Lagerprodukt Margin:"+Carrier1.Mstorehouse.getQuantity ()); Carrier2.Moveout (50); System.out.println ("Lagerprodukt Margin:"+Carrier2.Mstorehouse.getQuantity ()); }}Ergebnis:
Sind die beiden gleich? Produktspanne im selben Lagerhaus: 130 Lagerproduktspanne: 50
2. Einführung in das Singleton -Muster
2.1 Probleme gelöst (Anwendungsszenarien)
Konflikt: Aus den oben genannten Ergebnissen ist ersichtlich, dass die Arbeitnehmer offensichtlich nicht die gleiche Lagerinstanz.
Ziel: Alle Arbeiter betreiben die gleiche Lagerinstanz
Singleton -Muster ist eine Lösung für diese Art von Problem
In Java betreiben wir diese Klassen mithilfe von Objekten (nach der Klasseninstanziierung). Die Instanziierung der Klasse wird durch seinen Konstruktor durchgeführt . Wenn wir implementieren möchten, dass eine Klasse nur ein sofortiges Objekt hat, müssen wir am Konstruktor der Klasse arbeiten:
Allgemeine Implementierung des Singleton -Modus: (einschließlich Verwendungsschritte)
öffentliche Klasse Singleton {// 1. Erstellen Sie eine private Variable Ourinstance (verwendet, um eine einzigartige Instanz von Singleton aufzuzeichnen) // 2. INOFANTIEREN SIE INDANTIERT INDANTIERT INDANTIEREN SIE UNTERUNGEN UNSERNEHMEN OURINSTANCE = NEW SINGLETON (); // 3. Privatisieren Sie den Konstruktor der Klasse und verhindern Sie externe Aufrufe, private Singleton () {} // 4 zu instanziieren. Definieren Sie eine öffentliche Methode, um einen globalen einzigartigen Zugangspunkt für die Klasse // 5 bereitzustellen. EXTERNAL eine einzigartige Instanz zurückgeben, indem Sie die GetInstance () -Methode public static Singleton NewInstance () {return OurInstance; }}OK, Sie sollten die Einführung und Prinzipien des Singleton -Musters verstehen, oder? Lassen Sie uns also das Problem lösen, dass "das Lagerhaus nicht das gleiche ist", das über Xiacheng erschien!
2.3 Beispiel Einführung
Xiaangeng verwendet den Singleton -Modus, um den Code für das obige Beispiel zu verbessern:
Paket scut.designmodel.singletonpattern; import java.util.concurrent.locks.lock; import Java.util.concurrent // private statische Lagerhaus in Instanziierung von OurInstance = New Lagerhouse () ;; // Lassen Sie die externe Methode GetInstance () aufrufen, um die eindeutige Instanz zurückzugeben. public static sagerhouse getInstance () {return OurInstance; } // Closed Constructor Private Storehouse () {} public void setQuantity (int Menge) {this.quantity = mantity; } public int getQuantity () {return quantity; }} // Carrier Man Class Carrier {Public Storehouse Mstorehouse; Public Carrier (Lagerhaus Lagerhaus) {Mstorehouse = Lagerhaus; } // Waren in das Warehouse public void movein (int i) {mstorehouse.setQuantity (mstorehouse.getQuantity ()+i); } // Aus dem Warehouse public void moveout (int i) {mstorehouse.setQuantity (mstorehouse.getQuantity ()-i); }} // Arbeiterhandling Test public class SinglePattern {public static void main (String [] args) {Lagerhaus mstorehouse1 = storehouse.getInstance (); Lagerhaus mstorehouse2 = soruehouse.getInstance (); Carrier Carrier1 = neuer Träger (Mstorehouse1); Carrier Carrier2 = neuer Träger (Mstorehouse2); System.out.println ("Sind die beiden gleich?"); if (mstorehouse1.equals (mstorehouse2)) {System.out.println ("ist das gleiche"); } else {system.out.println ("nicht dasselbe"); } // Nachdem der Porter die Ware bewegt hat, melden Sie die Warenmenge im Lagerhaus, Carrier1.Movein (30); System.out.println ("Lagerprodukt Margin:"+Carrier1.Mstorehouse.getQuantity ()); Carrier2.Moveout (50); System.out.println ("Lagerprodukt Margin:"+Carrier2.Mstorehouse.getQuantity ()); }}Ergebnis:
Sind die beiden gleich? Es ist der gleiche Warehouse -Rohstoffrand: 130 Warehouse Commodity Margin: 80
Laut der Ergebnisanalyse gibt es nach der Verwendung des Singleton -Modells nur eine Lagerinstanz in der Lagerklasse, und es müssen sich keine Sorgen machen, dass Träger, die in das falsche Lager gehen, eintreten! ! !
2.4 Vorteile
2.5 Nachteile
3. Implementierung des Singleton -Modus
3.1 Allgemeine Situation
Hungriger Stil (die einfachste Singleton -Implementierungsmethode)
Klasse Singleton {private statische Singleton Ourinstance = New Singleton (); private Singleton () {} public static Singleton newInstance () {return OurInstance; }}Anwendungsszenarien:
Fauler Stil
Der größte Unterschied zwischen Lazy und Hungry ist der Zeitpunkt der Initialisierungsoperation von Singletons :
Klasse Singleton {private statische Singleton Ourinstance = null; private Singleton () {} public static Singleton newInstance () {if (Ourinstance == null) {Ourinstance = new Singleton (); } as uremine stance; }}Anwendungsszenarien:
3.2 Implementierung des Singleton -Modus unter Multithreading
Im Fall von Multithreading:
Lösung 1: Synchronisieren Sie das Schloss
Verwenden Sie die Synchronisationsschloss Synchronized (Singleton.Class), um zu verhindern, dass mehrere Threads gleichzeitig eintreten, was dazu führt, dass die Instanz mehrmals instanziiert wird.
Klasse Singleton {private statische Singleton Ourinstance = null; private singleton () {} public static Singleton NewInstance () {synchronized (Singleton.class) {if (Ourinstance == null) {Ourinstance = new Singleton (); }} return Ourinstance; }}Lösung 2: Doppelkontrollschloss
Eine Schicht von If wird auf der Grundlage der Synchronisationsschloss (außer synchronisiert (Singleton.Class)), um die Leistung zu verbessern, nachdem die Instanz instanziiert wurde. Wenn sie das nächste Mal eintritt, muss sie nicht synchronisiert (Singleton.Class) ausführen, um die Objektschloss zu erhalten und die Leistung zu verbessern.
Klasse Singleton {private statische Singleton Ourinstance = null; private Singleton () {} public static Singleton newInstance () {if (ourInstance == null) {synchronized (Singleton.class) {if (ourinstance == null) {Ourinstance = new Singleton (); }}} return Ourinstance; }}Lösung 3: Statische innere Klasse
Wenn die JVM -Klasse lädt, wird die Daten garantiert synchronisiert. Wir verwenden interne Klassenimplementierung: Erstellen Sie Objektinstanzen in der internen Klasse.
Solange die Anwendung die interne Klassen -JVM nicht verwendet, wird die Singleton -Klasse nicht geladen und das Singleton -Objekt wird nicht erstellt, wodurch "faul" faule Lade- und Thread -Sicherheit erreicht wird.
Klasse Singleton {// Das Singleton -Objekt wird nur erstellt, wenn die innere Klasse private statische Klasse Singleton2 {private statische Singleton Ourinstance = New Singleton () ist; } private Singleton () {} public static Singleton NewInstance () {return Singleton2.ourinstance; }}Lösung 4: Aufzählende Typen
Die einfachste und benutzerfreundliche Singleton-Implementierungsmethode (empfohlen von "effektiver Java")
public enum singleton {// ein Enum -Element definieren, das eine Instanz der Singleton -Instanz ist; public void dosomething () {}}Wie man es benutzt, ist wie folgt:
Singleton Singleton = Singleton.instance; Singleton.dosomething ();
5. Zusammenfassung
In diesem Artikel wird hauptsächlich das Singleton -Modell vorgestellt, einschließlich der Prinzipien und Implementierungsmethoden. Als nächstes werde ich weiterhin andere Designmodelle erklären. Wenn Sie interessiert sind, können Sie weiterhin darauf achten.
Danke fürs Lesen, ich hoffe, es kann Ihnen helfen. Vielen Dank für Ihre Unterstützung für diese Seite!