El patrón Singleton es probablemente el patrón de diseño más utilizado. Es un patrón simple, fácil de entender y de usar. En ocasiones se utiliza en exceso y en escenarios donde no es necesario. En tales casos, las desventajas de su uso superan las ventajas que aporta. Por esta razón, el patrón singleton a veces se considera un antipatrón o patrón singleton .
Temas importantes para el patrón de diseño del método Singleton
- ¿Qué es el patrón de diseño del método Singleton?
- ¿Cuándo utilizar el patrón de diseño del método Singleton?
- Tipos de inicialización de Singleton
- Componente clave del patrón de diseño del método Singleton:
- Implementación del patrón de diseño del método Singleton
- Diferentes formas de implementar el patrón de diseño del método Singleton
- Caso de uso del método de patrón singleton
- Ventajas del patrón de diseño del método Singleton:
- Desventajas del patrón de diseño Singleton
1. ¿Qué es el patrón de diseño del método Singleton?
El método Singleton o patrón Singleton Design es uno de los patrones de diseño más simples. Garantiza que una clase solo tenga una instancia y proporciona un punto de acceso global a ella.

2. ¿Cuándo utilizar el patrón de diseño del método Singleton?
Utilice el patrón de diseño del método Singleton cuando:
cómo convertir una cadena a un int
- Debe haber exactamente una instancia de una clase y debe ser accesible para los clientes desde un punto de acceso conocido.
- Cuando la instancia única debe ser extensible mediante subclases y los clientes deben poder usar una instancia extendida sin modificarla
- Las clases Singleton se utilizan para registros, objetos de controlador, almacenamiento en caché y conexiones de bases de datos y grupos de subprocesos.
3. Tipos de inicialización de Singleton
Se pueden crear instancias de la clase Singleton mediante dos métodos:
tutorial de lenguaje de programación java
- Inicialización temprana: En este método, la clase se inicializa independientemente de si se va a utilizar o no. La principal ventaja de este método es su simplicidad. Inicias la clase en el momento de cargar la clase. Su inconveniente es que la clase siempre se inicializa tanto si se utiliza como si no.
- Inicialización diferida: En este método, la clase se inicializa solo cuando es necesario. Puede evitarle crear una instancia de la clase cuando no la necesita. Generalmente, la inicialización diferida se utiliza cuando creamos una clase singleton.
4. Componente clave del patrón de diseño del método Singleton:
4.1. Miembro estático:
El patrón Singleton o patrón Singleton emplea un miembro estático dentro de la clase. Este miembro estático garantiza que la memoria se asigne solo una vez, preservando la instancia única de la clase Singleton.
Java
// Static member to hold the single instance private static Singleton instance;>
4.2. Constructor Privado:
El patrón Singleton o patrón singleton incorpora un constructor privado, que sirve como barricada contra intentos externos de crear instancias de la clase Singleton. Esto asegura que la clase tenga control sobre su proceso de creación de instancias.
Java // Private constructor to // prevent external instantiation class Singleton { // Making the constructor as Private private Singleton() { // Initialization code here } }>
4.3. Método de fábrica estática:
Un aspecto crucial del patrón Singleton es la presencia de un método de fábrica estático. Este método actúa como una puerta de enlace y proporciona un punto de acceso global al objeto Singleton. Cuando alguien solicita una instancia, este método crea una nueva instancia (si no existe ninguna) o devuelve la instancia existente a la persona que llama.
Java // Static factory method for global access public static Singleton getInstance() { // Check if an instance exists if (instance == null) { // If no instance exists, create one instance = new Singleton(); } // Return the existing instance return instance; }>
5. Implementación del patrón de diseño del método Singleton
La implementación de un Patrón de Diseño Singleton o Patrón Singleton se describe en el siguiente diagrama de clases:

Implementación del patrón de diseño del método Singleton
10 1 millón
La implementación del patrón de diseño singleton es muy sencilla y consta de una única clase. Para garantizar que la instancia singleton sea única, todos los constructores singleton deben hacerse privados. El acceso global se realiza a través de un método estático al que se puede acceder globalmente a una sola instancia como se muestra en el código.
Java /*package whatever //do not write package name here */ import java.io.*; class Singleton { // static class private static Singleton instance; private Singleton() { System.out.println('Singleton is Instantiated.'); } public static Singleton getInstance() { if (instance == null) instance = new Singleton(); return instance; } public static void doSomething() { System.out.println('Somethong is Done.'); } } class GFG { public static void main(String[] args) { Singleton.getInstance().doSomething(); } }>
Producción
Singleton is Instantiated. Somethong is Done.>
Con el método getInstance, verificamos si la instancia es nula. Si la instancia no es nula, significa que el objeto se creó antes; de lo contrario, lo creamos usando el nuevo operador.
6. Diferentes formas de implementar el patrón de diseño del método Singleton
A veces necesitamos tener solo una instancia de nuestra clase, por ejemplo, una única conexión de base de datos compartida por varios objetos, ya que crear una conexión de base de datos separada para cada objeto puede resultar costoso. De manera similar, puede haber un único administrador de configuración o administrador de errores en una aplicación que maneje todos los problemas en lugar de crear múltiples administradores.
Veamos varias opciones de diseño para implementar dicha clase. Si tiene un buen manejo de las variables de clase estáticas y los modificadores de acceso, esta no debería ser una tarea difícil.
sumador lleno
Método 1 – Implementación clásica || Hacer getInstance() estático para implementar Patrón de diseño del método Singleton
Java // Classical Java implementation of singleton // design pattern class Singleton { private static Singleton obj; // private constructor to force use of // getInstance() to create Singleton object private Singleton() {} public static Singleton getInstance() { if (obj == null) obj = new Singleton(); return obj; } }>
Aquí hemos declarado obtener Instancia() static para que podamos llamarlo sin crear una instancia de la clase. La primera vez obtener Instancia() se llama, crea un nuevo objeto singleton y después de eso, simplemente devuelve el mismo objeto.
Nota: El objeto singleton no se crea hasta que lo necesitamos y llamamos al obtener Instancia() método. Esto se llama instanciación diferida. El principal problema con el método anterior es que no es seguro para subprocesos. Considere la siguiente secuencia de ejecución.
Esta secuencia de ejecución crea dos objetos para el singleton. Por lo tanto, esta implementación clásica no es segura para subprocesos.
Método 2 || Hacer que getInstance() se sincronice para implementar Patrón de diseño del método Singleton
Java // Thread Synchronized Java implementation of // singleton design pattern class Singleton { private static Singleton obj; private Singleton() {} // Only one thread can execute this at a time public static synchronized Singleton getInstance() { if (obj == null) obj = new Singleton(); return obj; } }>
Aquí, el uso de sincronizado garantiza que solo se pueda ejecutar un subproceso a la vez. obtener Instancia() . La principal desventaja de este método es que usar sincronizado cada vez que se crea el objeto singleton es costoso y puede disminuir el rendimiento de su programa. Sin embargo, si el desempeño de obtener Instancia() no es crítico para su aplicación, este método proporciona una solución limpia y simple.
Método 3 – Creación de instancias ansiosa || Implementación basada en inicializador estático del patrón de diseño singleton
Java // Static initializer based Java implementation of // singleton design pattern class Singleton { private static Singleton obj = new Singleton(); private Singleton() {} public static Singleton getInstance() { return obj; } }>
Aquí hemos creado una instancia de un singleton en un inicializador estático. JVM ejecuta un inicializador estático cuando se carga la clase y, por lo tanto, se garantiza que es seguro para subprocesos. Utilice este método sólo cuando su clase singleton sea ligera y se utilice durante toda la ejecución de su programa.
Método 4 – Más eficiente || Utilice el bloqueo de doble verificación para implementar el patrón de diseño singleton
Si observa con atención una vez que se crea un objeto, la sincronización ya no es útil porque ahora obj no será nulo y cualquier secuencia de operaciones conducirá a resultados consistentes. Por lo tanto, solo adquiriremos el bloqueo en getInstance() una vez cuando el obj sea nulo. De esta manera solo sincronizamos el primer paso, justo lo que queremos.
lista de matrices en javaJava
// Double Checked Locking based Java implementation of // singleton design pattern class Singleton { private static volatile Singleton obj = null; private Singleton() {} public static Singleton getInstance() { if (obj == null) { // To make thread safe synchronized (Singleton.class) { // check again as multiple threads // can reach above step if (obj == null) obj = new Singleton(); } } return obj; } }>
Hemos declarado el obj. volátil lo que garantiza que varios subprocesos ofrezcan la variable obj correctamente cuando se inicializa en la instancia Singleton. Este método reduce drásticamente la sobrecarga de llamar al método sincronizado cada vez.
7. Caso de uso del método de patrón singleton
- Conexiones de bases de datos: En aplicaciones donde crear y administrar conexiones de bases de datos es una operación costosa, se puede utilizar un Singleton para mantener una única conexión de base de datos en toda la aplicación.
- Gestión de configuración: Cuando tiene ajustes de configuración global a los que deben acceder varios componentes de la aplicación, un administrador de configuración Singleton puede proporcionar un único punto de acceso a estos ajustes.
- Componentes de la GUI: Para componentes o controladores de interfaz gráfica de usuario (GUI), un Singleton puede ayudar a administrar el estado y las acciones de la interfaz de usuario, proporcionando un único punto de control.
- Administradores de dispositivos: En sistemas integrados o aplicaciones que interactúan con dispositivos de hardware, se puede utilizar un Singleton para administrar y controlar el acceso a los dispositivos de hardware para evitar conflictos.
- Servicio de impresión: En sistemas que implican la impresión de documentos o informes, un servicio de impresión Singleton puede coordinar y gestionar los trabajos de impresión, garantizando un uso eficiente de los recursos de impresión.
8. Ventajas del patrón de diseño del método Singleton:
- Resuelve colisiones de nombres: En escenarios donde se necesita un único punto de control para evitar conflictos o colisiones de nombres, el patrón Singleton garantiza que solo haya una instancia con un nombre único.
- Inicialización ansiosa o perezosa: El patrón Singleton admite tanto la inicialización ansiosa (crear la instancia cuando se carga la clase) como la inicialización diferida (crear la instancia cuando se solicita por primera vez), lo que proporciona flexibilidad según el caso de uso.
- Seguridad del hilo: Los patrones Singleton implementados correctamente pueden proporcionar seguridad para los subprocesos, garantizando que la instancia se cree de forma atómica y que varios subprocesos no creen instancias duplicadas sin darse cuenta.
- Huella de memoria reducida: En aplicaciones donde el consumo de recursos es crítico, el patrón Singleton puede contribuir a reducir el uso de memoria al garantizar que solo haya una instancia de la clase.
9. Desventajas del patrón de diseño Singleton
- Dificultades de la prueba: Debido a que los Singleton introducen el estado global, las pruebas unitarias pueden resultar desafiantes. Probar un componente de forma aislada puede ser más complicado si se basa en un Singleton, ya que el estado del Singleton puede afectar el resultado de las pruebas.
- Problemas de concurrencia: En un entorno de subprocesos múltiples, puede haber problemas relacionados con la creación e inicialización de la instancia Singleton. Si varios subprocesos intentan crear el Singleton simultáneamente, puede generar condiciones de carrera.
- Extensibilidad limitada: El patrón Singleton puede hacer que el código sea menos extensible. Si luego decide que necesita varias instancias de la clase o desea cambiar la lógica de creación de instancias, es posible que requiera una refactorización significativa.
- Dependencia global: El patrón Singleton crea una dependencia global, lo que hace que sea más difícil reemplazar Singleton con una implementación alternativa o usar la inyección de dependencia para proporcionar instancias.
- Difícil de subclasificar: Subclasificar un Singleton puede ser un desafío. Debido a que el constructor suele ser privado, extender un Singleton requiere cuidado adicional y es posible que no siga patrones de herencia estándar.
- Gestión del ciclo de vida: Es posible que el patrón Singleton no maneje escenarios en los que la instancia deba destruirse o restablecerse explícitamente. Gestionar el ciclo de vida del Singleton puede convertirse en una preocupación.
- Abuso de puntos de acceso global: Si bien un punto de acceso global es una ventaja, también se puede abusar de él. Los desarrolladores podrían verse tentados a utilizar Singleton para todo, lo que llevaría a un uso excesivo del estado global y a un diseño menos modular.
10. Conclusión
Es importante que algunas clases tengan exactamente una instancia. Aunque puede haber muchas impresoras en un sistema, solo debe haber una cola de impresión. Sólo debería haber un sistema de archivos y un administrador de ventanas. Un filtro digital tendrá un convertidor A/D. Un sistema de contabilidad estará dedicado a servir a una empresa. ¿Cómo nos aseguramos de que una clase tenga solo una instancia y que la instancia sea fácilmente accesible? Una variable global hace que un objeto sea accesible, pero no impide crear instancias de varios objetos.
Una mejor solución es hacer que la clase misma sea responsable de realizar un seguimiento de su única instancia. La clase puede garantizar que no se pueda crear otra instancia (interceptando solicitudes para crear nuevos objetos) y puede proporcionar una forma de acceder a la instancia. Este es el patrón Singleton.