Pregunta ¿Qué hay de malo en singletons? [cerrado]


los patrón singleton es un miembro totalmente pagado de la GoFes libro de patrones, pero últimamente parece bastante huérfano para el mundo de los desarrolladores. Todavía uso bastantes singletons, especialmente para clases de fábrica, y aunque tienes que ser un poco cuidadoso con los problemas de subprocesamiento múltiple (como cualquier clase en realidad), no veo por qué son tan horribles.

Stack Overflow especialmente parece suponer que todos están de acuerdo en que los Singleton son malvados. ¿Por qué?

Por favor apoya tus respuestas con "hechos, referencias o experiencia específica"


1737


origen


Respuestas:


Parafraseado de Brian Button:

  1. Generalmente se usan como una instancia global, ¿por qué es eso tan malo? Porque oculta las dependencias de su aplicación en su código, en lugar de exponerlas a través de las interfaces. Hacer algo global para evitar pasarlo es una olor a código.

  2. Ellos violan el principio de responsabilidad única: en virtud del hecho de que controlan su propia creación y ciclo de vida.

  3. Inherentemente causan que el código esté estrechamente acoplado. Esto hace que fingirlos bajo prueba sea bastante difícil en muchos casos.

  4. Transmiten estado durante toda la vida de la aplicación. Otro golpe para las pruebas ya que puede terminar con una situación en la que se deben pedir pruebas, lo que es un gran no, no para las pruebas unitarias. ¿Por qué? Porque cada prueba unitaria debe ser independiente de la otra.


1148



Singletons resuelve un (y solo uno) problema.

Contención de recursos.

Si tienes algún recurso que

(1) solo puede tener una sola instancia, y

(2) necesita administrar esa única instancia,

tu necesitas un semifallo.

No hay muchos ejemplos. Un archivo de registro es el más grande. No desea simplemente abandonar un único archivo de registro. Desea enjuagarlo, sincronizarlo y cerrarlo correctamente. Este es un ejemplo de un único recurso compartido que debe ser administrado.

Es raro que necesites un singleton. La razón por la que son malos es que se sienten como un global y son un miembro completamente pagado del GoF Patrones de diseño libro.

Cuando crees que necesitas un global, probablemente estés cometiendo un terrible error de diseño.


399



Algunos snobs de codificación los desprecian como un mundo glorificado. De la misma manera que muchas personas odian el ir declaración hay otros que odian la idea de utilizar alguna vez global. He visto a varios desarrolladores hacer esfuerzos extraordinarios para evitar global porque consideraron usar uno como una admisión de fracaso. Extraño pero cierto.

En la práctica, Semifallo el patrón es solo una técnica de programación que es una parte útil de su conjunto de herramientas de conceptos. De vez en cuando, puede encontrar que es la solución ideal, así que úselo. Pero usándolo solo para que pueda jactarse de usar un patrón de diseño es tan estúpido como negarse a usarlo porque es solo una global.


306



Misko Hevery, de Google, tiene algunos artículos interesantes sobre exactamente este tema ...

Singletons son mentirosos patológicos tiene un ejemplo de prueba de unidad que ilustra cómo los singletons pueden dificultar la identificación de cadenas de dependencia y comenzar o probar una aplicación. Es un ejemplo bastante extremo de abuso, pero el punto que él hace sigue siendo válido:

Los singletons no son más que un estado global. El estado global lo hace para que tus objetos puedan obtener secretamente cosas que no están declaradas en sus API, y, como resultado, los Singleton convierten tus API en mentirosos patológicos.

¿Dónde se han ido todos los Singletons? señala que la inyección de dependencias ha facilitado la obtención de instancias a los constructores que las requieren, lo que alivia la necesidad subyacente detrás de los malvados Singleton globales denunciados en el primer artículo.


200



Creo que la confusión está causada por el hecho de que las personas no conocen la aplicación real del patrón de Singleton. No puedo enfatizar esto lo suficiente. Singleton es no un patrón para envolver a los globales. El patrón Singleton solo debe usarse para garantizar que una y solo una instancia de una clase dada existe durante el tiempo de ejecución.

La gente piensa que Singleton es malo porque lo están usando para lo global. Es por esta confusión que Singleton es despreciado. Por favor, no confundas Singletons y globales. Si se usa para el propósito para el que fue diseñado, obtendrá beneficios extremos del patrón de Singleton.


103



Una cosa bastante mala de los singleton es que no puedes extenderlos muy fácilmente. Básicamente tienes que construir en algún tipo de patrón de decorador o algo así si quieres cambiar su comportamiento. Además, si un día desea tener múltiples formas de hacer una cosa, puede ser bastante doloroso cambiar, dependiendo de cómo diseñe su código.

Una cosa a tener en cuenta es que si usas singletons, intenta pasarlos a quien los necesite en lugar de hacer que accedan directamente a ellos ... De lo contrario, si alguna vez eliges tener múltiples formas de hacer lo que singleton hace, será es bastante difícil de cambiar ya que cada clase incorpora una dependencia si accede directamente al singleton.

Así que básicamente:

public MyConstructor(Singleton singleton) {
    this.singleton = singleton;
}

más bien que:

public MyConstructor() {
    this.singleton = Singleton.getInstance();
}

Creo que este tipo de patrón se llama inyección de dependencia y generalmente se considera una buena cosa.

Sin embargo, como cualquier patrón ... Piénselo y considere si su uso en la situación dada es inapropiado o no ... Las reglas están hechas para romperse generalmente, y patrones no se debe aplicar sin pensar o sin pensar.


71



El patrón singleton no es un problema en sí mismo. El problema es que el patrón suele ser utilizado por personas que desarrollan software con herramientas orientadas a objetos sin tener una comprensión sólida de los conceptos de OO. Cuando se introducen singletons en este contexto, tienden a convertirse en clases inmanejables que contienen métodos auxiliares para cada uso.

Los singletons también son un problema desde una perspectiva de prueba. Tienden a hacer pruebas unitarias aisladas difíciles de escribir. Inversión de control (IoC) y inyección de dependencia son patrones destinados a superar este problema de una manera orientada a objetos que se presta a pruebas unitarias.

en un basura recolectada los singletons de entorno pueden convertirse rápidamente en un problema con respecto a la gestión de memoria.

También existe el escenario de subprocesos múltiples en el que los singletons pueden convertirse en un cuello de botella y en un problema de sincronización.


65



Un singleton se implementa utilizando un método estático. Los métodos estáticos son evitados por personas que realizan pruebas unitarias porque no se pueden burlar o tapar. La mayoría de las personas en este sitio son grandes defensores de las pruebas unitarias. La convención generalmente más aceptada para evitarlos es usar el Inversión de control patrón.


52