
En la programación orientada a objetos , el patrón singleton es un patrón de diseño de software que restringe la instanciación de una clase a una instancia singular. Uno de los conocidos patrones de diseño de la "Banda de los cuatro" , que describe cómo resolver problemas recurrentes en software orientado a objetos. [1] El patrón es útil cuando se necesita exactamente un objeto para coordinar acciones en un sistema.
Más específicamente, el patrón singleton permite que las clases: [2]
- Asegúrese de que solo tengan una instancia
- Proporcionar acceso fácil a esa instancia
- Controlar su instanciación (por ejemplo, ocultando los constructores de una clase )
El término proviene del concepto matemático de singleton .
Usos comunes
Los singletons suelen preferirse a las variables globales porque no contaminan el espacio de nombres global (o el espacio de nombres que lo contiene). Además, permiten una asignación e inicialización diferidas , mientras que las variables globales en muchos lenguajes siempre consumirán recursos. [1] [3]
El patrón singleton también se puede utilizar como base para otros patrones de diseño, como los patrones de fábrica abstracta , método de fábrica , constructor y prototipo . Los objetos de fachada también suelen ser singletons porque solo se necesita un objeto de fachada.
El registro es un caso de uso real común para singletons, porque todos los objetos que desean registrar mensajes requieren un punto de acceso uniforme y escriben conceptualmente en una única fuente. [4]
Implementaciones
Las implementaciones del patrón singleton garantizan que solo exista una instancia de la clase singleton y normalmente proporcionan acceso global a esa instancia.
Normalmente, esto se logra mediante:
- Declarar que todos los constructores de la clase son privados , lo que evita que otros objetos puedan crear instancias de la misma.
- Proporcionar un método estático que devuelve una referencia a la instancia
La instancia generalmente se almacena como una variable estática privada ; la instancia se crea cuando se inicializa la variable, en algún momento antes de que se llame por primera vez al método estático.
Esta implementación de C++11 se basa en la implementación anterior a C++98 del libro [ cita requerida ] .
#include <flujo de datos>
class Singleton { public : // define una operación de clase que permite a los clientes acceder a su instancia única. static Singleton & get () { // puede ser responsable de crear su propia instancia única. if ( nullptr == instance ) instance = new Singleton ; return * instance ; } Singleton ( const Singleton & ) = delete ; // regla de tres Singleton & operator = ( const Singleton & ) = delete ; static void destruct () { delete instance ; instance = nullptr ; } // la interfaz existente va aquí int getValue () { return value ; } void setValue ( int value_ ) { value = value_ ; } private : Singleton () = default ; // sin constructor público ~ Singleton () = default ; // sin destructor público static Singleton * instance ; // declaración de la variable de clase int value ; };
Singleton * Singleton :: instance = nullptr ; // definición de la variable de clase
int main () { Singleton :: obtener (). setValue ( 42 ); std :: cout << "valor=" << Singleton :: obtener (). getValue () << '\n' ; Singleton :: destruct (); }
La salida del programa es
valor = 42
Esta es una implementación del singleton de Meyers [5] en C++11. El singleton de Meyers no tiene método de destrucción. La salida del programa es la misma que la anterior.
#include <flujo de datos>
clase Singleton { público : Singleton estático y get () { instancia de Singleton estático ; instancia de retorno ; } int getValue () { valor de retorno ; } void setValue ( int valor_ ) { valor = valor_ ; } privado : Singleton () = predeterminado ; ~ Singleton () = predeterminado ; int valor ; };
int main () { Singleton :: obtener (). setValue ( 42 ); std :: cout << "valor=" << Singleton :: obtener (). getValue () << '\n' ; }
Inicialización perezosa
Una implementación singleton puede utilizar una inicialización diferida en la que la instancia se crea cuando se invoca por primera vez el método estático. En programas multiproceso , esto puede provocar condiciones de carrera que resulten en la creación de múltiples instancias. El siguiente ejemplo de Java 5+ [6] es una implementación segura para subprocesos , que utiliza una inicialización diferida con bloqueo de doble verificación .
clase pública Singleton {
instancia Singleton privada estática volátil = nula ;
Singleton privado () {}
público estático Singleton getInstance () { if ( instancia == null ) { sincronizado ( Singleton . class ) { if ( instancia == null ) { instancia = new Singleton (); } } } return instancia ; } }
Crítica
Algunos consideran que el singleton es un antipatrón que introduce un estado global en una aplicación, a menudo de forma innecesaria. Esto introduce una posible dependencia del singleton por parte de otros objetos, lo que requiere el análisis de los detalles de implementación para determinar si realmente existe una dependencia. [7] Este mayor acoplamiento puede introducir dificultades con las pruebas unitarias . [8] A su vez, esto impone restricciones a cualquier abstracción que utilice el singleton, como evitar el uso simultáneo de varias instancias. [8] [9] [10]
Los singletons también violan el principio de responsabilidad única porque son responsables de hacer cumplir su propia singularidad junto con el desempeño de sus funciones normales. [8]
Véase también
Referencias
- ^ de Erich Gamma, Richard Helm, Ralph Johnson y John Vlissides (1994). Patrones de diseño: elementos de software reutilizable orientado a objetos . Addison Wesley. pp. 127 y siguientes. ISBN 0-201-63361-2.
{{cite book}}: CS1 maint: varios nombres: lista de autores ( enlace ) - ^ "El patrón de diseño Singleton: problema, solución y aplicabilidad". w3sDesign.com . Consultado el 16 de agosto de 2017 .
- ^ Soni, Devin (31 de julio de 2019). "¿Qué es un singleton?". BetterProgramming . Consultado el 28 de agosto de 2021 .
- ^ Rainsberger, JB (1 de julio de 2001). "Use your singletons wisely". IBM. Archivado desde el original el 24 de febrero de 2021. Consultado el 28 de agosto de 2021 .
- ^ Scott Meyers (1997). Un C++ más eficaz . Addison Wesley. pp. 146 y siguientes. ISBN 0-201-63371-X.
- ^ Eric Freeman, Elisabeth Freeman, Kathy Sierra y Bert Bates (octubre de 2004). "5: Objetos únicos: el patrón Singleton". Patrones de diseño Head First (primera edición). O'Reilly Media, Inc., pág. 182. ISBN 978-0-596-00712-6.
{{cite book}}: CS1 maint: varios nombres: lista de autores ( enlace ) - ^ "Por qué los singletons son controvertidos". Archivo de código de Google . Archivado desde el original el 6 de mayo de 2021. Consultado el 28 de agosto de 2021 .
- ^ Steve Yegge. Los solteros considerados estúpidos, septiembre de 2004
- ^ Hevery, Miško, "Estado global y singletons", Clean Code Talks , 21 de noviembre de 2008.
Enlaces externos
- Artículo completo "Explicación del patrón singleton de Java"
- Cuatro formas diferentes de implementar singleton en Java "Formas de implementar singleton en Java"
- Extracto del libro: Implementación del patrón Singleton en C# por Jon Skeet
- Singleton en el Centro para desarrolladores de patrones y prácticas de Microsoft
- Artículo de IBM "Bloqueo con doble verificación y el patrón Singleton" de Peter Haggar
- Geary, David (25 de abril de 2003). "Cómo navegar por el patrón Singleton engañosamente simple". Patrones de diseño de Java. JavaWorld . Consultado el 21 de julio de 2020 .
- Detector de singletons de Google (analiza el código de bytes de Java para detectar singletons)
