Mi granito de java: Singleton

jueves, 26 de mayo de 2011

Singleton

La idea del patrón Singleton es proveer un mecanismo para limitar el número de instancias de una clase. Por lo tanto el mismo objeto es siempre compartido por distintas partes del código. Puede ser visto como una solución más elegante para una variable global porque los datos son abstraídos por detrás de la interfaz que publica la clase singleton.
Dicho de otra manera, esta patrón busca garantizar que una clase sólo tenga una instancia y proporcionar un punto de acceso global a ella.

Usaremos este patrón cuando:
♦ Debe haber exactamente una instancia de una clase y deba ser accesible a los clientes desde un punto de acceso conocido.
♦ Se requiere de un acceso estandarizado y conocido públicamente.

Sus usos más comunes son clases que representan objetos unívocos. Por ejemplo, si hay un servidor que necesita ser representado mediante un objeto, este debería ser único, es decir, debería existir una sola instancia y el resto de las clases deberían de comunicarse con el mismo servidor. Un Calendario, por ejemplo, también es único para todos.
No debe utilizarse cuando una clase esta representando a un objeto que no es único, por ejemplo, la clase Persona no debería ser Singleton, ya que representa a una persona real y cada persona tiene su propio nombre, edad, domicilio, DNI, etc.


Diagrama UML
En el diagrama, la clase que es Singleton define una instancia para que los clientes puedan accederla. Esta instancia es accedida mediante un método de clase.
Los clientes (quienes quieren acceder a la clase Singleton) acceden a la única instancia mediante un método llamado getInstance().

Ejemplo.

Como dije anteriormente, este patrón es ideal para aquellas clases que representan objetos únicos. Por ejemplo, un instituto educativo es un objeto único. No deberíamos crear muchas instancias de esta clase ya que al hacer esto estaríamos diciendo que hay varios institutos educativos. Caso contrario serían los alumnos que asisten a dicho instituto. Debería haber un objeto por cada uno de los alumnos, ya que todos ellos tienen propiedades distintivas, desde el nombre hasta el documento de identidad. Pero todos los alumnos deberían comunicarse con el mismo instituto.

Entonces, haremos que el instituto aplique el patrón Singleton:


Para llamar al instituto debemos hacer lo siguiente:




Bien, veamos ahora este mismo ejemplo, con una pequeña modificación: vamos a agregarle un atributo a la clase InstitutoEducativo y veremos como se comporta a lo largo de las distintas llamadas al método getInstance().

Y, el main, que representa al cliente que necesita utilizar esta clase:




Otros temas a considerar.
 
Como vimos, el Singleton es un patrón sencillo para aplicar. Solo requiere de unos pequeños cambios a una clase. Sin embargo, debemos considerar un tema importante con respecto a este patrón: ¿que pasa si dos hilos del programa llaman (la primera vez) al método getInstance() al mismo tiempo? Bueno aqui podriamos tener un problema, ya que existe la remota posibilidad de que se logre crear dos instancias de la clase, en vez de una como quisieramos. La solución más sencilla es realizar un pequeño cambio:



¿Hay más soluciones para que el Singleton sea Thread Safe? Si, podemos ver algunas de ellas en http://en.wikipedia.org/wiki/Singleton_pattern

19 comentarios:

Anónimo dijo...

excelente explicacion... muchas gracias crack!!!

Max dijo...

Gracias a vos!

Anónimo dijo...

excelente , muchas gracias por compartir!
saludos

Seba dijo...

Es tremenda la habilidad que tenes para explicar, mas claro que en muchisimos libros! Saludos y gracias

Max dijo...

Muchas gracias! :)

Anónimo dijo...

Perfecto, muchas gracias, es increíble lo mal que había entendido esto y lo bien q ahora se acomodó en mi mente ahora

Sebastian dijo...

Gracias , excelente explicación, mas claro no se puede jojojo.

Anónimo dijo...

Que buena explicación! Gracias por tu granitoDeJava :D

Anónimo dijo...

muy bueno muchasg racias

Cris dijo...

Gracias por la explicación, ha sido la mas clara que he encontrado.
Dios le Bendice

UI_R&W dijo...

es un ejemplo perfecto!gracias!!

Sora dijo...

Es justo lo que buscaba, gracias por este tipo de aportes y sobretodo por hacer una explicacion digerible ;)

Anónimo dijo...

Es lo que estaba buscando muchas gracias

Anónimo dijo...

Hola muchas gracias por tus explicaciones.
Soy un poco o mucho novato.
Una pregunta ¿tendrías que haber declarado la clase Singleton como final?, para evitar la creación de mas objetos Singleton a traves de sus subclases.
O tal vez lo has explicado así para simplificar el concepto
Gracias de nuevo
Saludos

Anónimo dijo...

Hola de nuevo.
Soy el anónimo un poco novato o realmente muy novato.
No podríamos crear subclases ya que no podríamos acceder al constructor de la superclase que es private.
Espero que sea esta la respuesta a mi pregunta.
Gracias
Saludos

Anónimo dijo...

Excelente implementación, gracias crack. Justo lo que buscaba.

Anónimo dijo...

Excelente implementación, gracias crack. Justo lo que buscaba.

Anónimo dijo...

Es la primera vez que escucho de este tema y la explicación fue muy clara, solo no entendi la última modificación, pero igual Muchas Gracias.

Unknown dijo...

Hola tengo una consulta, si tengo la clase Banco, Cliente y Cuenta, donde la clase banco son entidades bancarias, cliente son clientes del banco y la clase cuenta son las cuentas de ahorro etc, que tiene un cliente. A cual de estas clases se debe aplicar Singleton, se lo que significa Singleton instanciar solo una vez a una clase. Lo que no tengo muy claro es en que casos se debe aplicar. En el caso de las clases seria a la clase cuenta??? por favor tu ayuda, para tener claro esta definición.