296 votos

Singleton: ¿Cómo debe ser utilizado

Edición: Desde otra pregunta que me dio una respuesta que tiene enlaces a un montón de preguntas/respuestas acerca de los embarazos únicos: Más información acerca de los embarazos únicos aquí:

Así que he leído el hilo Singleton: un buen diseño o una muleta?
Y el argumento sigue haciéndolo.

Veo Singleton como un Patrón de Diseño (buenas y malas).

El problema con Singleton no es el Patrón, sino la de los usuarios (lo siento a todo el mundo). Todo el mundo y su padre piensa que puede aplicar correctamente (y una de las muchas entrevistas que he hecho, la mayoría de la gente no puede hacer). También porque todo el mundo piensa que puede implementar una correcta Singleton que el abuso de los patrones y de utilizarlo en situaciones que no son adecuadas (en sustitución de variables globales con los embarazos Únicos!).

Así que las principales preguntas que necesitan ser contestadas son:

  • Cuando se debe utilizar un Singleton
  • ¿Cómo implementar un Singleton correctamente

Mi deseo para este artículo es que podemos reunir en un solo lugar (en lugar de tener a google y buscar en varios sitios) de una fuente de autoridad de cuándo (y cómo) para el uso de un Singleton correctamente. También apropiado sería una lista de Anti-Usos comunes y malas implementaciones de explicar por qué fallan al trabajo y para el bien de las implementaciones de sus debilidades.


Para conseguir el balanceo de la bola:
Voy a tomar mi mano y decir esto es lo que yo uso, pero probablemente tiene problemas.
Me gusta "Scott Myers" la manipulación de la materia en sus libros "Effective C++"

Buenas Situaciones para utilizar Singleton (no muchos):

  • El registro de marcos
  • Hilo de piscinas de reciclaje
/*
 * C++ Singleton
 * Limitation: Single Threaded Design
 * See: http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf
 *      For problems associated with locking in multi threaded applications
 *
 * Limitation:
 * If you use this Singleton (A) within a destructor of another Singleton (B)
 * This Singleton (A) must be fully constructed before the constructor of (B)
 * is called.
 */
class MySingleton
{
    private:
        // Private Constructor
        MySingleton();
        // Stop the compiler generating methods of copy the object
        MySingleton(MySingleton const& copy);            // Not Implemented
        MySingleton& operator=(MySingleton const& copy); // Not Implemented

    public:
        static MySingleton& getInstance()
        {
            // The only instance
            // Guaranteed to be lazy initialized
            // Guaranteed that it will be destroyed correctly
            static MySingleton instance;
            return instance;
        }
};

ACEPTAR. Le permite llegar a algunas críticas y otras implementaciones juntos.
:-)

183voto

Javaxpert Puntos 1107

Todos ustedes están equivocados. Leer la pregunta. Respuesta:

El uso de un Singleton si:

  • Si usted necesita para tener uno y sólo un objeto de un tipo en el sistema

No utilice un Singleton si:

  • Si desea guardar la memoria
  • Si quieres probar algo nuevo
  • Si quieres mostrar lo mucho que sabes
  • Porque todos los demás están haciendo (Ver carga de culto programador en wikipedia)
  • En la interfaz de usuario de widgets
  • Se supone que esto es un caché
  • En las cadenas de
  • En Las Sesiones De
  • Puedo ir todo el día

Cómo crear la mejor singleton:

  • El más pequeño, mejor. Yo soy un minimalista
  • Asegúrese de que es seguro para subprocesos
  • Asegúrese de que nunca es nula
  • Asegúrese de que se crea sólo una vez
  • Perezoso o la inicialización del sistema? Hasta sus requisitos
  • A veces el sistema operativo o la JVM crea singleton para usted (por ejemplo. en Java cada definición de clase es un singleton)
  • Proporcionar un destructor o de alguna manera de averiguar cómo disponer de los recursos
  • El poco uso de memoria

74voto

jalf Puntos 142628

Singleton le dan la posibilidad de combinar dos malos rasgos de una clase. Que hay de malo en casi todos los sentidos.

Un singleton te ofrece:

  1. El acceso Global a un objeto, y
  2. Una garantía de que no hay más de un objeto de este tipo nunca puede ser creado

El número uno es sencillo. Globals generalmente son malas. Nunca debemos hacer que los objetos de acceso global a menos que realmente lo necesitan.

El número dos puede parecer que tiene sentido, pero vamos a pensar acerca de esto. Cuando fue la última vez que *accidentalmente crea un nuevo objeto en lugar de hacer referencia a uno existente? Ya que este es etiquetado C++, vamos a utilizar un ejemplo de ese idioma. ¿A menudo accidentalmente escribir

std::ostream os;
os << "hello world\n";

Cuando la intención de escribir

std::cout << "hello world\n";

Por supuesto que no. No necesitamos protección en contra de este error, porque ese tipo de error, simplemente no sucede. Si lo hace, la respuesta correcta es ir a casa y dormir de 12 a 20 horas y la esperanza de que usted se sienta mejor.

Si sólo uno de los objetos es necesario, simplemente, crear una instancia. Si un objeto debe ser accesible a nivel mundial, hacen que sea un mundial. Pero eso no significa que no sea posible crear otras instancias de la misma.

"Sólo una instancia que es posible" restricción realmente no nos protegen contra la probabilidad de errores. Pero hace nuestro código muy duro para volver a producir y mantener. Porque muy a menudo descubrimos más tarde que se nos hizo necesario más de una instancia. Nos hacen tener más de una base de datos, que nos hacen tener más de un objeto de configuración, queremos varios registradores. Nuestra unidad de pruebas desea, puede ser capaz de crear y recrear estos objetos de cada prueba, para tomar un ejemplo común.

Así que un singleton debe ser utilizado si y solo si, necesitamos tanto de las características que ofrece: Si tenemos la necesidad de acceso global (lo cual es raro, porque globals generalmente se recomienda) y tenemos la necesidad de evitar que alguien alguna vez la creación de más de una instancia de una clase (que me suena a un problema de diseño. La única razón por la que puedo ver es que si la creación de dos instancias corruptos de nuestro estado de la aplicación, probablemente porque la clase contiene un número de miembros estáticos o similares de la estupidez. En el que caso de que la respuesta obvia es la de fijar que el de la clase. No debería depender de ser la única instancia.

Si usted necesita el acceso global a un objeto, hacer un mundial, como std::cout. Pero no limitar el número de instancias que se pueden crear.

Si estoy absolutamente necesario para limitar el número de instancias de una clase a uno, y no hay ninguna manera la creación de dos instancias jamás puede ser manejado con seguridad, exigir que. Pero no lo hacen accesible a nivel mundial así.

Si usted necesita ambos rasgos, entonces 1) hacer un singleton, y 2) que me haga saber lo que usted necesita para que, porque yo estoy teniendo un tiempo difícil imaginar un caso.

37voto

DrPizza Puntos 9355

El problema con los embarazos únicos, no es su implementación. Es que confunden dos conceptos diferentes, ninguno de los cuales es obviamente deseable.

1) los Únicos proporcionar un global mecanismo de acceso a un objeto. A pesar de que podría ser un poco más seguro para subprocesos o ligeramente más confiable en las idiomas sin una bien definida orden de inicialización, este uso es todavía el equivalente moral de una variable global. Es una variable global vestido en algún torpe sintaxis (foo::get_instance() en lugar de g_foo, digamos), pero sirve para el mismo propósito (un solo objeto accesible a través de todo el programa) y tiene exactamente el mismo inconveniente.

2) los Únicos evitar múltiples instancias de una clase. Es raro, IME, que este tipo de característica debe ser horneado en una clase. Normalmente es mucho más contextuales cosa; muchas de las cosas que son consideradas como uno y sólo uno en realidad sólo pasa-a-ser-solo-uno. IMO una solución más adecuada es crear una sola instancia, hasta que te das cuenta de que necesitas más de una instancia.

28voto

Paweł Hajdan Puntos 8004

Una cosa con patrones: no generalizar. Ellos tienen todos los casos cuando son útiles, y cuando ellos fallan.

Singleton puede ser desagradable cuando usted tiene que probar el código. Usted está por lo general atascada con una instancia de la clase, y puede elegir entre abrir una puerta en el constructor o algún método para restablecer el estado y así sucesivamente.

Otro problema es que el Singleton en realidad no es más que una variable global en el disfraz. Cuando usted tiene demasiado global compartida de estado en el transcurso de su programa, las cosas tienden a ir de nuevo, todos lo sabemos.

Se puede hacer el seguimiento de dependencia más difícil. Cuando todo depende de su Singleton, es más difícil que la cambie, divida en dos, etc. Usted está por lo general se pegó con él. Esto también dificulta la flexibilidad. Investigar algunos de Inyección de Dependencia marco para intentar paliar este problema.

14voto

Eli Courtwright Puntos 53071

Singleton, básicamente, permiten tener un complejo estado global en las lenguas que de lo contrario, hacer que sea difícil o imposible tener complejo de variables globales.

Java, en particular, los usos únicos como un reemplazo para las variables globales, ya que todo debe estar contenida dentro de una clase. La más cercana se trata de variables globales son públicas las variables estáticas, que puede ser utilizado como si fueran global, import static

C++ tiene a las variables globales, pero el orden en el que los constructores de la clase global variables se invoca es indefinido. Como tal, un singleton le permite aplazar la creación de una variable global hasta la primera vez que la variable es necesario.

Lenguajes como Python y Ruby utilizar singleton muy poco porque puede utilizar las variables globales dentro de un módulo en su lugar.

Así que cuando es bueno/malo para el uso de un singleton? Bastante exactamente cuándo sería bueno/malo para utilizar una variable global.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X