Singleton
Notas de clase
¿Que es el patron singleton?
Singleton
es un patrón de diseño creacional que nos permite asegurarnos de que una clase
tenga una única instancia, a la vez que proporciona un punto de acceso global a
dicha instancia.
Problema
1: Garantizar que las clases tengan una sola instancia ¿Por qué querría alguien
controlar cuántas instancias tiene una clase? El motivo más habitual es controlar el
acceso a algún recurso compartido, por ejemplo, una base de datos o un archivo.
Funciona así: imagina que has creado un objeto y al cabo de un tiempo decides crear
otro nuevo. En lugar de recibir un objeto nuevo, obtendrás el que ya habías creado.
Ten en cuenta que este comportamiento es imposible de implementar con un
constructor normal, ya que una llamada al constructor siempre debe devolver un
nuevo objeto por diseño.
2:Proporcionar un punto de acceso a global dichas Instancia:
¿ recuerdas estas variables globales que utilizaste (bueno, sí, fui yo) para almacenar
objetos esenciales? Aunque son muy útiles, también son poco seguras, ya que
cualquier código podría sobrescribir el contenido de esas variables y descomponer la
aplicación.
Al igual que una variable global, el patrón Singleton nos permite acceder a un objeto
desde cualquier parte del programa. No obstante, también evita que otro código
sobreescriba esa instancia.
Singleton 1
Este problema tiene otra cara: no queremos que el código que resuelve el primer
problema se encuentre disperso por todo el programa. Es mucho más conveniente
tenerlo dentro de una clase, sobre todo si el resto del código ya depende de ella.
Hoy en día el patrón Singleton se ha popularizado tanto que la gente suele
llamar singleton a cualquier patrón, incluso si solo resuelve uno de los problemas
antes mencionados.
Solucion al problema
Todas las implementaciones del patrón Singleton tienen estos dos pasos en común:
Hacer privado el constructor por defecto para evitar que otros objetos utilicen el
operador new con la clase Singleton.
Crear un método de creación estático que actúe como constructor. Tras
bambalinas, este método invoca al constructor privado para crear un objeto y lo
guarda en un campo estático. Las siguientes llamadas a este método devuelven el
objeto almacenado en caché.
Si tu código tiene acceso a la clase Singleton, podrá invocar su método estático. De
esta manera, cada vez que se invoque este método, siempre se devolverá el mismo
objeto.
Estructura del patron
Singleton 2
Aplicabilidad
Utiliza el patrón Singleton cuando una clase de tu programa tan solo deba tener
una instancia disponible para todos los clientes; por ejemplo, un único objeto de
base de datos compartido por distintas partes del programa.
El patrón Singleton deshabilita el resto de las maneras de crear objetos de una clase,
excepto el método especial de creación. Este método crea un nuevo objeto, o bien
devuelve uno existente si ya ha sido creado.
Utiliza el patrón Singleton cuando necesites un control más estricto de las
variables globales.
Al contrario que las variables globales, el patrón Singleton garantiza que haya una
única instancia de una clase. A excepción de la propia clase Singleton, nada puede
sustituir la instancia en caché.
Singleton 3
Ten en cuenta que siempre podrás ajustar esta limitación y permitir la creación de
cierto número de instancias Singleton. La única parte del código que requiere cambios
es el cuerpo del método getInstance .
Como implementarlo
1. Añade un campo estático privado a la clase para almacenar la instancia Singleton.
2. Declara un método de creación estático público para obtener la instancia
Singleton.
3. Implementa una inicialización diferida dentro del método estático. Debe crear un
nuevo objeto en su primera llamada y colocarlo dentro del campo estático. El
método deberá devolver siempre esa instancia en todas las llamadas siguientes.
4. Declara el constructor de clase como privado. El método estático de la clase
seguirá siendo capaz de invocar al constructor, pero no a los otros objetos.
5. Repasa el código cliente y sustituye todas las llamadas directas al constructor de
la instancia Singleton por llamadas a su método de creación estático.
Pros y contras
Pros: Contras
Puedes tener la certeza de que una Vulnera el Principio de
clase tiene una única instancia. responsabilidad única. El patrón
resuelve dos problemas al mismo
Obtienes un punto de acceso global
tiempo.
a dicha instancia.
El patrón Singleton puede
El objeto Singleton solo se inicializa
enmascarar un mal diseño, por
cuando se requiere por primera vez.
ejemplo, cuando los componentes
del programa saben demasiado los
unos sobre los otros.
El patrón requiere de un tratamiento
especial en un entorno con múltiples
hilos de ejecución, para que varios
hilos no creen un objeto Singleton
varias veces.
Singleton 4
Puede resultar complicado realizar la
prueba unitaria del código cliente del
Singleton porque
muchos frameworks de prueba
dependen de la herencia a la hora
de crear objetos simulados (mock
objects). Debido a que la clase
Singleton es privada y en la mayoría
de los lenguajes resulta imposible
sobrescribir métodos estáticos,
tendrás que pensar en una manera
original de simular el Singleton. O,
simplemente, no escribas las
pruebas. O no utilices el patrón
Singleton.
Codigo Hecho en java
El codigo siguiente nos muestra como implementar singleton en este caso crearemos
varias Clases:
Persona
Base Datos(Implementara singleton)
Casa
Main
Cada casa que se cree tiene personas.
una persona tiene atributos como edad y el nombre.
La base datos que solo se creara una instancia de ellla permitira guardar todas las
persona que esten en diferentes casas
Vamos al codigo…
Singleton 5
clase base Datos
import [Link];
public class BaseDatos {
//Cramos una instancia global de la base de datos
private static BaseDatos bd;
private ArrayList<Persona> personas;
private BaseDatos(){
personas = new ArrayList<>();
}
public static BaseDatos obtenerInstancia(){
//Comprobamos si ya se creo un objeto si es null le damos valor a nuestro parametro
if(bd == null){
bd = new BaseDatos();
}
return bd;
}
public void addPersona(Persona p){
[Link](p);
}
public ArrayList<Persona> mandarPersonas(){
return [Link];
}
Clase persona
public class Persona {
public Persona(String nombre, int edad) {
[Link] = nombre;
[Link] = edad;
}
private String nombre;
private int edad;
public String getNombre() {
return nombre;
}
public int getEdad() {
return edad;
}
}
Singleton 6
Clase casa
import [Link];
public class Casa {
private ArrayList<Persona> inquilinos;
private int numeroCasa;
public Casa(int numeroCasa) {
[Link] = numeroCasa;
inquilinos = new ArrayList<>();
}
public void agregarInquilino(Persona p){
BaseDatos bd = [Link]();
[Link](p);
[Link](p);
}
Clase main
public class App {
public static void main(String[] args) throws Exception {
/*haremos uso del patron singleton que se trata de de que solo se
cree una solo instancia de la clase que esa sera usado entonces lo comun esto
se aplica en creacion de base de datos cuando solo queremos uno*/
//crearemos casa y le agregaremis personas
Casa casa1 = new Casa(1);
[Link](new Persona("jose", 20));
[Link](new Persona("maria", 21));
[Link](new Persona("pablo", 10));
Casa casa2 = new Casa(2);
[Link](new Persona("talia", 31));
[Link](new Persona("rocio", 30));
[Link]("se mostrara todas la persona");
BaseDatos bd = [Link]();
for(Persona p: [Link]() ){
[Link]([Link]());
[Link]([Link]());
[Link]();
}
}
}
Singleton 7
Este documento describe el patrón de diseño Singleton, que se utiliza para garantizar
que una clase tenga una única instancia y proporcionar un punto de acceso global a
dicha instancia. El patrón se utiliza para controlar el acceso a recursos compartidos y
evitar que otros códigos sobrescriban la instancia. El documento también describe la
estructura del patrón, su aplicabilidad y cómo implementarlo en Java. Además, se
presentan los pros y contras del patrón, incluyendo la violación del principio de
responsabilidad única y la dificultad para realizar pruebas unitarias. Se presenta un
ejemplo de cómo implementar el patrón Singleton en Java para crear una base de
datos compartida entre diferentes casas.
Singleton 8