El patrón singleton es uno de los patrones más utilizados en Java. Se utiliza para controlar el número de objetos creados evitando la creación de instancias y modificaciones externas. Este concepto se puede generalizar a sistemas que operan de manera más eficiente cuando solo existe un objeto, o que restringen la instanciación a un cierto número de objetos, tales como:
- constructor privado: ninguna otra clase puede crear una instancia de un nuevo objeto.
- referencia privada – sin modificación externa.
- El método estático público es el único lugar que puede obtener un objeto.
La historia de Singleton
Aquí hay un caso de uso simple. Un país solo puede tener un presidente. Entonces, cuando se necesita un presidente, el único presidente debe ser devuelto en lugar de crear uno nuevo. La getPresident()
El método se asegurará de que siempre haya un solo presidente creado.
Diagrama y código de clase
Modo ansioso:
public class AmericaPresident { private static final AmericaPresident thePresident = new AmericaPresident(); private AmericaPresident() {} public static AmericaPresident getPresident() { return thePresident; } } |
thePresident
se declara como final
, por lo que siempre contendrá la misma referencia de objeto.
Modo perezoso:
public class AmericaPresident { private static AmericaPresident thePresident; private AmericaPresident() {} public static AmericaPresident getPresident() { if (thePresident == null) { thePresident = new AmericaPresident(); } return thePresident; } } |
Patrón Singleton utilizado en la biblioteca de soporte de Java
java.lang.Runtime#
es un método de uso frecuente de la biblioteca estándar de Java. getRunTime()
devuelve el objeto de tiempo de ejecución asociado con la aplicación Java actual.
class Runtime { private static Runtime currentRuntime = new Runtime(); public static Runtime getRuntime() { return currentRuntime; } private Runtime() {} //... } |
Aquí hay un ejemplo simple de uso getRunTime()
. Lee una página web en un sistema Windows.
Process p = Runtime.getRuntime().exec( "C:/windows/system32/ping.exe programcreek.com"); //get process input stream and put it to buffered reader BufferedReader input = new BufferedReader(new InputStreamReader( p.getInputStream())); String line; while ((line = input.readLine()) != null) { System.out.println(line); } input.close(); |
Producción:
Pinging programcreek.com [198.71.49.96] with 32 bytes of data: Reply from 198.71.49.96: bytes=32 time=53ms TTL=47 Reply from 198.71.49.96: bytes=32 time=53ms TTL=47 Reply from 198.71.49.96: bytes=32 time=52ms TTL=47 Reply from 198.71.49.96: bytes=32 time=53ms TTL=47 Ping statistics for 198.71.49.96: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), Approximate round trip times in milli-seconds: Minimum = 52ms, Maximum = 53ms, Average = 52ms
Otra implementación del patrón singleton
Como el constructor privado no protege de la creación de instancias a través de la reflexión, Joshua Bloch (Effective Java) propone una mejor implementación de Singleton. Si no está familiarizado con Enum, aquí es un buen ejemplo de Oracle.
public enum AmericaPresident{ INSTANCE; public static void doSomething(){ //do something } } |
* Gracias al comentario de Dan.