Análisis de patrones de diseño de instancias simples de Singleton
Prefacio
Hoy le daré un resumen completo del patrón de diseño más utilizado en el desarrollo de Android: el modo Singleton.
Con respecto a la introducción a los patrones de diseño, puede leer lo que escribí antes: 1 minuto para comprender completamente los "patrones de diseño"
Tabla de contenido
1. Introducir
1.1 Qué problemas se resuelven
Como se mencionó anteriormente, el patrón de diseño = una solución a un cierto tipo de problema específico, entonces, ¿qué problema es el patrón de singleton ?
Significado: Singleton = una instancia;
Problema resuelto: reduzca el acoplamiento entre objetos
Solución: Patrón singleton, es decir, implementando que una clase solo tiene un objeto instanciado y proporciona un punto de acceso global
1.2 Introducción de instancia
A continuación, uso una instancia para introducir el patrón Singleton
Antecedentes: Xiaocheng tiene una fábrica de plásticos, pero solo hay un almacén adentro.
Propósito: Quiero usar el código para implementar la gestión del almacén
Prácticas actuales: establecer almacenes y trabajadores
Entre ellos, la cantidad en la clase del almacén = la cantidad de bienes; Los trabajadores tienen los métodos de manejo que se mueven (int i) y se mudan (int i).
Problemas: a través de las pruebas, se descubrió que cada vez que un trabajador se muda, se construirá un nuevo almacén, es decir, los productos no se colocan en el mismo almacén. ¿Qué está sucediendo? (Ver el código a continuación)
paquete scut.designmodel.singletonpattern; // almacén de clases de la tienda de clases {private int citandity = 100; public void setQuantity (int cantidad) {this.quantity = cantidad; } public int getQuantity () {cantidad de retorno; }} // Caminata de clase humana {Public Storehouse MStorehouse; Public Carrier (Storehouse Storehouse) {mStoreHouse = Storehouse; } // Mover bienes al almacén público vacío Void (int i) {mStoreHouse.SetQuantity (mStoreHouse.getQuantity ()+i); } // mudarse del almacén publicóok de la almacenamiento (int i) {mStoreHouse.SetQuantity (mStoreHouse.getQuantity ()-i); }} // prueba de manejo de trabajadores Clase pública SinglePatnN {public static void main (string [] args) {storehouse mstoreHouse1 = new storehouse (); Storehouse mstorehouse2 = new Storehouse (); Portador portador1 = nuevo portador (mStoreHouse1); Portador portador2 = nuevo portador (mStoreHouse2); System.out.println ("¿Son los dos iguales?"); if (mStoreHouse1.equals (mStoreHouse2)) {// Use iguales aquí en lugar del símbolo ==, porque el símbolo == es solo para comparar las direcciones de los dos objetos System.out.println ("es el mismo"); } else {System.out.println ("no es el mismo"); } // Después de que el portero mueva los bienes, informe la cantidad de bienes en el portador de almacén1.movein (30); System.out.println ("Margen de producto de almacén:"+portador1.mstorehouse.getQuantity ()); Transportador2.movout (50); System.out.println ("Margen de producto de almacén:"+portador2.mstorehouse.getQuantity ()); }}resultado:
¿Son los dos iguales? Margen de producto en el mismo almacén: 130 Almacenamiento Margen de producto: 50
2. Introducción al patrón Singleton
2.1 Problemas resueltos (escenarios de aplicación)
Conflicto: de los resultados anteriores, se puede ver que los trabajadores operaron obviamente no la misma instancia de almacén.
Objetivo: todos los trabajadores operan la misma instancia de almacén
Singleton Pattern es una solución a este tipo de problema: implementar una clase con solo un objeto instanciado y proporciona un principio de trabajo del punto de acceso global 2.2
En Java, operamos estas clases usando objetos (después de la instancia de clase). La instancia de clase se realiza a través de su constructor . Si queremos implementar que una clase solo tenga un objeto instanciado, tenemos que trabajar en el constructor de la clase:
Implementación general del modo Singleton: (incluidos los pasos de uso)
Singleton de clase pública {// 1. Cree una variable privada de nuestra Intervisión (se utiliza para grabar una instancia única de Singleton) // 2. Instanciar interno privado static singleton ourInstance = new Singleton (); // 3. Privatice el constructor de la clase y evite las llamadas externas para instanciar Singleton private () {} // 4. Defina un método público para proporcionar un punto de acceso único global para la clase // 5. Devuelva externamente una instancia única llamando al método getInStance () público static singleton newInstance () {return ourInstance; }}Ok, debes entender la introducción y los principios del patrón de singleton, ¿verdad? ¡Así que resolvamos el problema de que "el almacén no es el mismo" que apareció por encima de Xiaocheng!
2.3 Introducción de ejemplo
Xiaocheng usa el modo Singleton para mejorar el código para el ejemplo anterior:
paquete scut.designmodel.singletonpattern; import java.util.concurrent.locks.lock; import java.util.concurrent.locks.reentrantlock; // Singleton Warehouse Class Storehouse {// La cantidad de productos de almacenamiento intención privada = 100; // Instanciar el almacén estático privado OurInstance = New Storehouse () ;; // deja que la llamada externa el método getInstance () para devolver la instancia única. public static storehouse getInstance () {return ourInstance; } // Constructor cerrado Storehouse () {} public void setQuantity (int Cantidad) {this.quantity = cantidad; } public int getQuantity () {cantidad de retorno; }} // Carrier de clase Man Carrier {public storehouse mstorehouse; Public Carrier (Storehouse Storehouse) {mStoreHouse = Storehouse; } // Mueve los bienes al almacén public void Movein (int i) {mstorehouse.setQuantity (mStoreHouse.getQuantity ()+i); } // mudarse del almacén publicóok de la almacenamiento (int i) {mStoreHouse.SetQuantity (mStoreHouse.getQuantity ()-i); }} // prueba de manejo de trabajadores Clase pública SinglePatnn {public static void main (string [] args) {storehouse mstoreHouse1 = storehouse.getInstance (); Storehouse mstorehouse2 = storehouse.getInstance (); Portador portador1 = nuevo portador (mStoreHouse1); Portador portador2 = nuevo portador (mStoreHouse2); System.out.println ("¿Son los dos iguales?"); if (mstorehouse1.equals (mStoreHouse2)) {System.out.println ("es el mismo"); } else {System.out.println ("no lo mismo"); } // Después de que el portero mueva los bienes, informe la cantidad de bienes en el almacén, portador1.movein (30); System.out.println ("Margen de producto de almacén:"+portador1.mstorehouse.getQuantity ()); Transportador2.movout (50); System.out.println ("Margen de producto de almacén:"+portador2.mstorehouse.getQuantity ()); }}resultado:
¿Son los dos iguales? Es el mismo margen de productos básicos del almacén: 130 Margen de productos básicos del almacén: 80
Según el análisis de resultados, después de usar el modelo Singleton, solo hay una instancia de almacén en la clase de almacén, ¡y no hay necesidad de preocuparse por los porteros que ingresan al almacén equivocado! ! !
2.4 Ventajas
2.5 Desventajas
3. Implementación del modo Singleton
3.1 Situación general
Estilo hambriento (el método de implementación de singleton más simple)
clase Singleton {private static singleton ourInstance = new Singleton (); private singleton () {} public static singleton NewInstance () {return ourInstance; }}Escenarios de aplicación:
Estilo perezoso
La mayor diferencia entre Lazy y Hungry es el momento de la operación de inicialización de los singletons :
clase Singleton {private static singleton ourInstance = null; private singleton () {} public static singleton newInstance () {if (ourInstance == null) {ourInstance = new Singleton (); } return ourInstance; }}Escenarios de aplicación:
3.2 Implementación del modo singleton en múltiples lectura
En el caso de la lectura múltiple:
Solución 1: Sincronizar bloqueo
Use bloqueo de sincronización sincronizado (singleton.class) para evitar que múltiples hilos ingresen simultáneamente, lo que hace que la instancia se instanciara varias veces.
clase Singleton {private static singleton ourInstance = null; Private Singleton () {} public static singleton NewInstance () {SynChronized (singleton.class) {if (ourInstance == null) {ourInstance = new Singleton (); }} return ourInstance; }}Solución 2: bloqueo de doble verificación
Una capa de IF se agrega sobre la base del bloqueo de sincronización (excepto sincronizado (singleton.class)) es mejorar el rendimiento después de que se haya instanciado la instancia y la próxima vez que ingrese, no tiene que ejecutar sincronizado (singleton.class) para obtener el bloqueo de objetos, mejorando así el rendimiento.
clase Singleton {private static singleton ourInstance = null; Private Singleton () {} public static singleton NewInstance () {if (ourInstance == null) {sincronizado (singleton.class) {if (ourInstance == null) {ourInstance = new Singleton (); }}} return ourInstance; }}Solución 3: clase interna estática
Cuando se carga la clase JVM, se garantiza que los datos se sincronizarán. Utilizamos la implementación de la clase interna: cree instancias de objetos en la clase interna.
Mientras la aplicación no use la clase interna JVM, la clase Singleton no se cargará, y el objeto Singleton no se creará, lo que logrará la carga de la carga y la seguridad de los subprocesos "perezosos".
Class Singleton {// El objeto Singleton se creará solo cuando la clase interna se cargue la clase estática privada Singleton2 {private static singleton ourInstance = new Singleton (); } private singleton () {} public static singleton NewInstance () {return singleton2.ourInstance; }}Solución 4: tipos de enumerados
El método de implementación de singleton más simple y fácil de usar (recomendado por "Java efectivo")
public enum Singleton {// Definir un elemento enum, que es una instancia de singleton; public void dosomething () {}}Cómo usarlo es el siguiente:
Singleton Singleton = Singleton.instance; Singleton.Dosomething ();
5. Resumen
Este artículo presenta principalmente el modelo Singleton, incluidos los principios y los métodos de implementación. A continuación, continuaré explicando otros modelos de diseño. Si está interesado, puede continuar prestando atención.
Gracias por leer, espero que pueda ayudarte. ¡Gracias por su apoyo para este sitio!