entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

2votos

Implementación del patrón singleton en Java

¿Qué es necesario cambiar en la implementación del patrón singleton siguiente para realmente lograr que sólo una instancia de la clase pueda ser instanciada?

public class BD {
    static BD singleton ;
    static {
        singleton = new BD() ;
    }
    public BD() {
        //....
    }
    static BD instancia() {
        return singleton
    }
}

0voto

Peter comentado

Como bien te dice Humberto, la definición del constructor debe ser privada para permitir sólo su invocación desde la propia clase.

4 Respuestas

4votos

El constructor de clase debe ser privado, de esta forma aseguras que ninguna otra clase pueda crear instancias de la clase Singleton.

1voto

cloudman Puntos4020

En caso de trabajar con multi-hilo, podrías tener problemas de sincronización al tener el metodo instancia() sin sincronizar. Declarar el método instancia como

synchronyzed static BD instancia(){
/../
}

podría ser una solución, además de lo dicho anteriormente por el compañero

1voto

angro Puntos160

Según he visto en varios sitios, una forma muy efectiva y que suelo usar es esta:

public class BD 
{
    private static class Singleton 
    {
        private static BD instance = new BD();
    }

    public static BD getInstance() 
    {
        return Singleton.instance;
    }

    private BD()
    {
        // Código del constructor
    }
}   

No he probado a ver si hay alguna forma de "cargarse" esto en un entorno multihilo, pero yo nunca he tenido problemas y suelo trabajar mucho con Singleton en entornos multihilo.

1voto

techack comentado

No he probado si tu codigo es 100% correcto, pero es un poco absurdo la creacion de una clase interna con el patron singleton. Lo suyo es directamente crear un campo con el singleton. El codigo es casi identico, salvo que eliminas la creacion de una clase interna.

public class BD 
{
    private static BD instance;

    public static BD getInstance() 
    {
        if(instance == null) instance = new BD();
        return instance;
    }

// Propiedades/atributos de su clase

    private BD()
    {
        // Código del constructor
    }
}   

0voto

angro comentado

Absurdo no sé, pero si buscas por ahí encontrarás por qué es eficiente. Al parecer es más seguro que poniendo la variable sin inner class porque no se inicializa hasta que no la usas por primera vez.

No sé cómo andará esta web con los links, pero sin buscar mucho, he encontrado esta epxlicación que lo aclara un poco.

http://www.theserverside.com/discussions/thread.tss?thread_id=35349

Ya te digo que no me lo he inventado yo, lo vi en muchos sitios y buscándolo por ahí en su momento encontré que era uno de los métodos más recomendados.

0voto

techack comentado

Ya te digo que lo que comentas de poner el singleton como clase interna no lo he probado, por lo que no voy a decir si es peor o mejor. He realizado algun que otro singleton en java y la forma facil y normal es la que comento (es cierto que es la mas basica, y como todos sabemos, cuanto mas basico mejor, pero depende de la situacion).
En lenguajes .net yo lo que hacia era una clase Singleton general, que seria padre de todas aquellas que lo necesitasen, por lo que la hice una vez y bye bye!!xD. En java estoy haber si puedo hacer alguna generica para no tener que estar repitiendo el codigo del singleton.

Aun asi, me guardo este codigo compi y en cuanto tenga ocasion lo pruebo y si puedp hablarlo con alguien que entienda mas le pedire cuentas (siempre me han comentado lo de que las inner class no eran buenas!! =). )
Saludos

2votos

pablo_g Puntos180

Según Joshua Bloch, que de esto sabe un rato, la mejor forma es mediante un Enum.

public enum Foo {
   INSTANCE;

}

Joshua Bloch explicó esta alternativa en la charla de I/O Google 2008 his Effective Java Reloaded talk at Google I/O 2008:

The Right Way to Implement a Serializable Singleton

 public enum Elvis {
       INSTANCE;
       private final String[] favoriteSongs =
           { "Hound Dog", "Heartbreak Hotel" };
       public void printFavorites() {
           System.out.println(Arrays.toString(favoriteSongs));
       }
   }

Edit: En su libro Effective Java explica lo siguiente:

"This approach is functionally equivalent to the public field approach, except that it is more concise, provides the serialization machinery for free, and provides an ironclad guarantee against multiple instantiation, even in the face of sophisticated serialization or reflection attacks. While this approach has yet to be widely adopted, a single-element enum type is the best way to implement a singleton."

Por favor, accede o regístrate para responder a esta pregunta.

Otras Preguntas y Respuestas


...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta