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:

  1. excelente explicacion... muchas gracias crack!!!

    ResponderEliminar
  2. excelente , muchas gracias por compartir!
    saludos

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

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

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

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

    ResponderEliminar
  7. muy bueno muchasg racias

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

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

    ResponderEliminar
  10. Es lo que estaba buscando muchas gracias

    ResponderEliminar
  11. 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

    ResponderEliminar
  12. 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

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

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

    ResponderEliminar
  15. 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.

    ResponderEliminar
  16. 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.

    ResponderEliminar