El patrón Singleton es un miembro totalmente desembolsado del GoF 's libro de patrones , pero últimamente parece bastante huérfano por el mundo desarrollador. Todavía uso muchos singletons, especialmente para las clases de fábrica , y aunque debes tener un poco de cuidado con los problemas de subprocesos múltiples (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 Singletons son malvados. ¿Por qué?
Respalde sus respuestas con " hechos, referencias o experiencia específica "
Respuestas:
Parafraseado de Brian Button:
Generalmente se usan como una instancia global, ¿por qué es 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 un olor a código .
Violan el principio de responsabilidad única : en virtud del hecho de que controlan su propia creación y ciclo de vida.
Inherentemente hacen que el código esté estrechamente acoplado . Esto hace que fingirlos bajo prueba sea bastante difícil en muchos casos.
Llevan el estado durante toda la vida de la aplicación. Otro éxito para las pruebas, ya que puede terminar con una situación en la que las pruebas deben ordenarse, lo cual es un gran no para las pruebas unitarias. ¿Por qué? Porque cada prueba unitaria debe ser independiente de la otra.
fuente
Los Singletons resuelven un (y solo un) problema.
Contención de recursos.
Si tienes algún recurso que
( 1 ) solo puede tener una única instancia, y
( 2 ) necesita administrar esa instancia única,
Necesitas un singleton .
No hay muchos ejemplos. Un archivo de registro es el grande. No desea simplemente abandonar un solo archivo de registro. Desea vaciar, sincronizar y cerrarlo correctamente. Este es un ejemplo de un único recurso compartido que debe gestionarse.
Es raro que necesites un singleton. La razón por la que son malos es que se sienten globales y son miembros totalmente pagados del libro GoF Design Patterns .
Cuando crees que necesitas un global, probablemente estés cometiendo un terrible error de diseño.
fuente
Algunos snobs de codificación los miran como un global glorificado. De la misma manera que muchas personas odian la declaración de goto , hay otros que odian la idea de usar un global . He visto a varios desarrolladores hacer todo lo posible para evitar un global porque consideraron usar uno como una admisión de falla. Extraño pero cierto.
En la práctica, el patrón Singleton 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 y, por lo tanto, úsela. Pero usarlo solo para jactarse de usar un patrón de diseño es tan estúpido como negarse a usarlo porque es simplemente global .
fuente
Misko Hevery, de Google, tiene algunos artículos interesantes sobre exactamente este tema ...
Los singletons son mentirosos patológicos tiene un ejemplo de prueba de unidad que ilustra cómo los singletons pueden dificultar la determinación de cadenas de dependencia e iniciar o probar una aplicación. Es un ejemplo bastante extremo de abuso, pero el punto que él hace es válido:
¿Dónde tienen todos los Singletons Gone? Señala que la inyección de dependencia ha facilitado la obtención de instancias para los constructores que los requieren, lo que alivia la necesidad subyacente detrás de los Singletons globales malos denunciados en el primer artículo.
fuente
Creo que la confusión es causada por el hecho de que las personas no conocen la aplicación real del patrón Singleton. No puedo enfatizar esto lo suficiente. Singleton no es un patrón para envolver globales. El patrón Singleton solo debe usarse para garantizar que existe una sola instancia de una clase determinada durante el tiempo de ejecución.
La gente piensa que Singleton es malvado porque lo está usando para los globales. Es a causa de esta confusión que Singleton es menospreciado. Por favor, no confunda Singletons y globals. Si se usa para el propósito para el que fue diseñado, obtendrá beneficios extremos del patrón Singleton.
fuente
setInstance
métodos antes.) Sin embargo, eso apenas importa: ese pito que "necesitaba" un singleton tampoco sabía nada sobre la encapsulación o lo que está mal con estado global mutable, por lo que ayudó (?) proporcionó setters para cada. soltero. campo. (Y sí, esto sucede. Mucho . Casi todos los singleton que he visto en la naturaleza eran mutables por diseño, y a menudo de maneragoto
etc. Pueden funcionar en muchos casos, pero, francamente, "funciona" no es suficiente: si quiere ir en contra de la sabiduría convencional, será mejor que pueda demostrar cómo su enfoque Es mejor que las soluciones convencionales. Y aún no he visto tal caso para el patrón Singleton.getInstance
método o un nombre similar, y evita la existencia de un segunda instancia Francamente, en ese punto, es posible que ni siquiera tenga una instancia.Una cosa bastante mala acerca de los singletons es que no puedes extenderlos muy fácilmente. Básicamente, debe incorporar algún tipo de patrón de decorador o algo similar si desea cambiar su comportamiento. Además, si un día desea tener múltiples formas de hacer eso, puede ser bastante doloroso cambiar, dependiendo de cómo diseñe su código.
Una cosa a tener en cuenta, si USTED usa singletons, intente pasarlos a quien los necesite en lugar de hacer que accedan directamente ... De lo contrario, si alguna vez elige tener varias formas de hacer lo que hace singletons, será bastante difícil de cambiar ya que cada clase incorpora una dependencia si accede directamente al singleton.
Así que básicamente:
más bien que:
Creo que este tipo de patrón se llama inyección de dependencia y generalmente se considera algo bueno.
Sin embargo, como cualquier patrón ... Piénselo y considere si su uso en la situación dada es inapropiado o no ... Las reglas generalmente se rompen, y los patrones no se deben aplicar de ninguna manera sin pensarlo.
fuente
getInstance()
, entonces (b) ya no es del todo cierto.getInstance()
, ha descartado efectivamente la única diferencia útil entre el patrón Singleton y una referencia ordinaria. En lo que respecta al resto del código, la soltería ya no es una propiedad. Solo la persona que llamagetInstance()
debe saber o incluso importar cuántas instancias hay. Con solo una persona que llama, le cuesta más esfuerzo y flexibilidad a la clase imponer de manera confiable la soltería que a la persona que llama simplemente almacenar una referencia y reutilizarla.El patrón singleton no es un problema en sí mismo. El problema es que el patrón a menudo es 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 pequeño uso.
Los singleton también son un problema desde una perspectiva de prueba. Tienden a dificultar la escritura de pruebas unitarias aisladas. La inversión de control (IoC) y la 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 entorno de recolección de basura, los singletons pueden convertirse rápidamente en un problema con respecto a la administración de memoria.
También existe el escenario de subprocesos múltiples donde los singletons pueden convertirse en un cuello de botella y en un problema de sincronización.
fuente
Un singleton se implementa utilizando un método estático. Las personas que realizan pruebas unitarias evitan los métodos estáticos porque no pueden burlarse ni tropezarse. 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 patrón de inversión de control .
fuente
Singleton
clase falsa . Sin embargo, eso complica enormemente el proceso de prueba. Por un lado, ahora debe poder descargar las clases a voluntad (no es realmente una opción en la mayoría de los idiomas) o iniciar una nueva máquina virtual para cada prueba (lea: las pruebas pueden tomar miles de veces más). Sin embargo, para dos, la dependenciaSingleton
es un detalle de implementación que ahora se está filtrando en todas sus pruebas.Los singletons también son malos cuando se trata de agrupamiento . Porque entonces, ya no tienes "exactamente un singleton" en tu aplicación.
Considere la siguiente situación: como desarrollador, debe crear una aplicación web que acceda a una base de datos. Para asegurarse de que las llamadas simultáneas a la base de datos no entren en conflicto, cree un subproceso guardado
SingletonDao
:Por lo tanto, está seguro de que solo existe un singleton en su aplicación y que todas las bases de datos pasan por este único
SingletonDao
. Su entorno de producción ahora se ve así:Todo está bien hasta ahora.
Ahora, considere que desea configurar varias instancias de su aplicación web en un clúster. Ahora, de repente tienes algo como esto:
Eso suena extraño, pero ahora tiene muchos singletons en su aplicación . Y eso es exactamente lo que se supone que no es un singleton: tener muchos objetos de él. Esto es especialmente malo si, como se muestra en este ejemplo, desea realizar llamadas sincronizadas a una base de datos.
Por supuesto, este es un ejemplo del mal uso de un singleton. Pero el mensaje de este ejemplo es: No puede confiar en que haya exactamente una instancia de un singleton en su aplicación, especialmente cuando se trata de agrupación.
fuente
fuente
El monopolio es el demonio y los singletons con estado no solo de lectura / mutable son el problema 'real' ...
Después de leer Singletons son mentirosos patológicos, como se sugiere en la respuesta de Jason, me encontré con este pequeño dato que proporciona el mejor ejemplo presentado de cómo los singletons a menudo se usan mal.
En la última declaración se está refiriendo al concepto del blog de "los solteros son mentirosos".
¿Cómo se aplica esto al Monopolio?
Para comenzar un juego de monopolio, primero:
Ahora, para cualquiera que realmente no haya jugado al monopolio, estos estándares son ideales en el mejor de los casos. Una derrota en el monopolio es difícil de tragar porque, el monopolio se trata de dinero, si pierdes tienes que ver minuciosamente al resto de los jugadores terminar el juego, y las pérdidas suelen ser rápidas y aplastantes. Por lo tanto, las reglas generalmente se tuercen en algún momento para servir el interés propio de algunos de los jugadores a expensas de los demás.
Entonces estás jugando al monopolio con tus amigos Bob, Joe y Ed. Estás construyendo rápidamente tu imperio y consumiendo participación de mercado a un ritmo exponencial. Tus oponentes se debilitan y comienzas a oler sangre (en sentido figurado). Su amigo Bob invirtió todo su dinero en bloquear todas las propiedades de bajo valor posibles, pero no está recibiendo un alto retorno de la inversión como esperaba. Bob, como un golpe de mala suerte, aterriza en su Boardwalk y es eliminado del juego.
Ahora el juego pasa de tirar dados amistosamente a asuntos serios. Bob se ha convertido en el ejemplo del fracaso y Joe y Ed no quieren terminar como 'ese tipo'. Entonces, siendo el jugador líder, de repente, te conviertes en el enemigo. Joe y Ed comienzan a practicar intercambios debajo de la mesa, inyecciones de dinero detrás de la espalda, intercambios de casas infravalorados y, en general, cualquier cosa que lo debilite como jugador hasta que uno de ellos llegue a la cima.
Luego, en lugar de que uno de ellos gane, el proceso comienza de nuevo. De repente, un conjunto finito de reglas se convierte en un objetivo en movimiento y el juego degenera en el tipo de interacciones sociales que constituirían la base de cada reality show de televisión de alto nivel desde Survivor. Por qué, porque las reglas están cambiando y no hay consenso sobre cómo / por qué / qué se supone que representan, y lo que es más importante, no hay una sola persona que tome las decisiones. Cada jugador en el juego, en ese momento, está haciendo sus propias reglas y se produce el caos hasta que dos de los jugadores están demasiado cansados para mantener la farsa y rendirse lentamente.
Entonces, si un libro de reglas para un juego representa con precisión un singleton, el libro de reglas de monopolio sería un ejemplo de abuso.
¿Cómo se aplica esto a la programación?
Además de todos los problemas obvios de sincronización y seguridad de subprocesos que presentan los singletons mutables ... Si tiene un conjunto de datos, que puede ser leído / manipulado por múltiples fuentes diferentes al mismo tiempo y existe durante la vida útil de la ejecución de la aplicación, Probablemente sea un buen momento para dar un paso atrás y preguntar "¿Estoy usando el tipo correcto de estructura de datos aquí".
Personalmente, he visto a un programador abusar de un singleton al usarlo como una especie de almacén de bases de datos entrelazadas en una aplicación. Habiendo trabajado en el código directamente, puedo dar fe de que fue lento (debido a todos los bloqueos de hilo necesarios para que sea seguro para el hilo) y una pesadilla para trabajar (debido a la naturaleza impredecible / intermitente de los errores de sincronización), y casi imposible de probar bajo condiciones de 'producción'. Claro, un sistema podría haberse desarrollado utilizando sondeo / señalización para superar algunos de los problemas de rendimiento, pero eso no resolvería los problemas con las pruebas y, ¿por qué molestarse cuando una base de datos 'real' ya puede lograr la misma funcionalidad en un sistema mucho más robusto? / manera escalable.
Un Singleton es solo una opción si necesita lo que proporciona un Singleton. Una instancia de solo lectura de escritura de un objeto. Esa misma regla también debería conectarse en cascada con las propiedades / miembros del objeto.
fuente
Singleton.getInstance()
. Un lenguaje que admita la reflexión podría solucionarlo configurando el campo donde se almacena la instancia de One True. Sin embargo, en mi opinión, las pruebas se vuelven un poco menos confiables una vez que has empezado a jugar con el estado privado de otra clase.¡Singleton no se trata de una sola instancia!
A diferencia de otras respuestas, no quiero hablar sobre lo que está mal con Singletons, ¡sino mostrarles lo poderosos e increíbles que son cuando se usan correctamente!
Solución : utilice un proceso de arranque de subproceso único para inicializar todas las dependencias de su singleton.
Solución : utilice el método Patrón de fábrica para burlarse
Puede asignar
MyModel
a laTestMyModel
clase que lo hereda, en todas partes, cuandoMyModel
se inyectará, se leTestMyModel
insertará. - Problema : los Singletons pueden causar pérdidas de memoria ya que nunca se eliminaron.Solución : Bueno, ¡deséchalos! Implemente una devolución de llamada en su aplicación para desechar correctamente un singletons, debe eliminar todos los datos vinculados a ellos y finalmente: eliminarlos de la fábrica.
Como dije en el título, singleton no se trata de una sola instancia.
fuente
Settings
objeto singleton al que se puede acceder desde cualquier widget para que cada widget sepa cómo formatear los números mostrados. Si no fuera un objeto accesible globalmente, tendría que inyectarlo en el constructor a todos y cada uno de los widgets en el constructor y mantener la referencia a él como una variable miembro. Esta es una terrible pérdida de memoria y tiempo.Mi respuesta sobre cómo los Singleton son malos es siempre, "son difíciles de hacer bien". Muchos de los componentes fundamentales de los lenguajes son singletons (clases, funciones, espacios de nombres e incluso operadores), al igual que los componentes de otros aspectos de la informática (localhost, ruta predeterminada, sistema de archivos virtual, etc.), y no es accidental. Si bien ocasionan problemas y frustración de vez en cuando, también pueden hacer que muchas cosas funcionen MUCHO mejor.
Los dos errores más grandes que veo son: tratarlo como algo global y no definir el cierre Singleton.
Todos hablan de Singleton como globales, porque básicamente lo son. Sin embargo, gran parte (lamentablemente, no todo) de la maldad en un mundo no proviene intrínsecamente de ser global, sino de cómo lo usas. Lo mismo va para Singletons. En realidad, más aún, ya que "instancia única" realmente no tiene que significar "accesible a nivel mundial". Es más un subproducto natural, y dado todo lo malo que sabemos que proviene de él, no deberíamos tener tanta prisa por explotar la accesibilidad global. Una vez que los programadores ven un Singleton, siempre parecen acceder a él directamente a través de su método de instancia. En su lugar, debe navegar hacia él como lo haría con cualquier otro objeto. La mayoría del código ni siquiera debería saber que se trata de un Singleton (acoplamiento flojo, ¿verdad?). Si solo un pequeño fragmento de código accede al objeto como si fuera global, se deshace mucho daño.
El contexto Singleton también es realmente importante. La característica definitoria de un Singleton es que hay "solo uno", pero la verdad es que es "solo uno" dentro de algún tipo de contexto / espacio de nombres. Por lo general, son uno de: uno por subproceso, proceso, dirección IP o clúster, pero también pueden ser uno por procesador, máquina, espacio de nombres de idioma / cargador de clases / lo que sea, subred, Internet, etc.
El otro error, menos común, es ignorar el estilo de vida Singleton. El hecho de que solo haya uno no significa que un Singleton es un omnipotente "siempre fue y siempre será", ni es generalmente deseable (los objetos sin principio y fin violan todo tipo de suposiciones útiles en el código, y solo deben emplearse en la más desesperada de las circunstancias.
Si evita esos errores, Singletons aún puede ser un PITA, aunque está listo para ver que muchos de los peores problemas se mitigan significativamente. Imagine un Java Singleton, que se define explícitamente como una vez por cargador de clases (lo que significa que necesita una política de seguridad de subprocesos), con métodos definidos de creación y destrucción y un ciclo de vida que dicta cuándo y cómo se invocan, y cuyo método de "instancia" tiene protección de paquete, por lo que generalmente se accede a través de otros objetos no globales. Sigue siendo una fuente potencial de problemas, pero ciertamente mucho menos problemas.
Lamentablemente, en lugar de enseñar buenos ejemplos de cómo hacer Singletons. Enseñamos malos ejemplos, dejamos que los programadores los usen por un tiempo y luego les digamos que son un mal patrón de diseño.
fuente
Ver Wikipedia Singleton_pattern
Referencias (solo referencias relevantes del artículo)
fuente
No es que los singletons en sí sean malos, pero el patrón de diseño GoF sí lo es. El único argumento realmente válido es que el patrón de diseño de GoF no se presta en lo que respecta a las pruebas, especialmente si las pruebas se ejecutan en paralelo.
Usar una sola instancia de una clase es una construcción válida siempre que aplique los siguientes medios en el código:
Asegúrese de que la clase que se utilizará como singleton implemente una interfaz. Esto permite implementar stubs o simulacros utilizando la misma interfaz
Asegúrese de que el Singleton sea seguro para subprocesos. Eso es un hecho.
El singleton debe ser de naturaleza simple y no demasiado complicado.
Durante el tiempo de ejecución de su aplicación, donde los singletons deben pasarse a un objeto dado, use una fábrica de clases que construya ese objeto y haga que la fábrica de clases pase la instancia de singleton a la clase que lo necesita.
Durante las pruebas y para garantizar un comportamiento determinista, cree la clase singleton como instancia separada, ya sea como la clase en sí misma o como un stub / simulacro que implemente su comportamiento y páselo como está a la clase que lo requiere. No use el factor de clase que crea ese objeto bajo prueba que necesita el singleton durante la prueba, ya que pasará la única instancia global del mismo, lo que anula el propósito.
Hemos utilizado Singletons en nuestras soluciones con un gran éxito que es comprobable y garantiza un comportamiento determinista en flujos de prueba paralelos.
fuente
Me gustaría abordar los 4 puntos en la respuesta aceptada, espero que alguien pueda explicar por qué estoy equivocado.
¿Por qué es malo ocultar dependencias en tu código? Ya hay docenas de dependencias ocultas (llamadas de tiempo de ejecución C, llamadas a API de sistema operativo, llamadas a funciones globales), y las dependencias singleton son fáciles de encontrar (busque por ejemplo ()).
"Hacer algo global para evitar pasarlo es un olor a código". ¿Por qué no se pasa algo para evitar que sea un solo olor a código?
Si está pasando un objeto a través de 10 funciones en una pila de llamadas solo para evitar un singleton, ¿es genial?
Principio de responsabilidad única: creo que esto es un poco vago y depende de su definición de responsabilidad. Una pregunta relevante sería, ¿por qué es importante agregar esta "responsabilidad" específica a una clase?
¿Por qué pasar un objeto a una clase lo hace más estrechamente acoplado que usar ese objeto como un singleton dentro de la clase?
¿Por qué cambia cuánto dura el estado? Los Singletons pueden crearse o destruirse manualmente, por lo que el control todavía está allí, y puede hacer que la vida sea la misma que la vida de un objeto que no sea Singleton.
En cuanto a las pruebas unitarias:
fuente
Vince Huston tiene estos criterios, que me parecen razonables:
fuente
Los singletons son malos desde un punto de vista purista.
Desde un punto de vista práctico, un singleton es una compensación entre tiempo de desarrollo y complejidad .
Si sabe que su aplicación no cambiará tanto, están bastante bien. Solo sepa que es posible que necesite refactorizar las cosas si sus requisitos cambian de manera inesperada (lo cual está bastante bien en la mayoría de los casos).
Los singletons a veces también complican las pruebas unitarias .
fuente
No hay nada intrínsecamente incorrecto en el patrón, suponiendo que se esté utilizando para algún aspecto de su modelo que sea verdaderamente único.
Creo que la reacción se debe a su uso excesivo que, a su vez, se debe al hecho de que es el patrón más fácil de entender e implementar.
fuente
No voy a comentar sobre el argumento del bien / el mal, pero no los he usado desde que llegó la primavera . El uso de la inyección de dependencia ha eliminado mis requisitos para singleton, servicelocators y fábricas. Me parece un entorno mucho más productivo y limpio, al menos para el tipo de trabajo que hago (aplicaciones web basadas en Java).
fuente
Singleton es un patrón y se puede usar o abusar como cualquier otra herramienta.
La parte mala de un singleton es generalmente el usuario (o debería decir el uso inapropiado de un singleton para cosas para las que no está diseñado). El mayor delincuente está usando un singleton como una variable global falsa.
fuente
Cuando escribe código usando singletons, digamos, un registrador o una conexión de base de datos, y luego descubre que necesita más de un registro o más de una base de datos, está en problemas.
Los Singletons hacen que sea muy difícil pasar de ellos a objetos normales.
Además, es demasiado fácil escribir un singleton que no sea seguro para subprocesos.
En lugar de usar singletons, debe pasar todos los objetos de utilidad necesarios de una función a otra. Eso se puede simplificar si los envuelve en un objeto auxiliar, como este:
fuente
El problema con los singletons es la cuestión del alcance ampliado y, por lo tanto, del acoplamiento . No se puede negar que hay algunas situaciones en las que se necesita acceso a una sola instancia, y se puede lograr de otras maneras.
Ahora prefiero diseñar alrededor de un contenedor de inversión de control (IoC) y permitir que las vidas sean controladas por el contenedor. Esto le brinda el beneficio de que las clases que dependen de la instancia desconocen el hecho de que hay una sola instancia. La vida útil del singleton se puede cambiar en el futuro. Una vez que el ejemplo que encontré recientemente fue un ajuste fácil de un solo subproceso a varios subprocesos.
FWIW, si es un PIA cuando intentas probarlo en la unidad, entonces se convertirá en PIA cuando intentes depurarlo, corregirlo o mejorarlo.
fuente
Artículo reciente sobre este tema por Chris Reath en Codificación sin comentarios .
Nota: La codificación sin comentarios ya no es válida. Sin embargo, el artículo al que está vinculado ha sido clonado por otro usuario.
http://geekswithblogs.net/AngelEyes/archive/2013/09/08/singleton-i-love-you-but-youre-bringing-me-down-re-uploaded.aspx
fuente
Los singletons NO son malos. Solo es malo cuando haces algo globalmente único que no es globalmente único.
Sin embargo, hay "servicios de ámbito de aplicación" (piense en un sistema de mensajería que hace que los componentes interactúen): esto LLAMA para un singleton, una "MessageQueue" - clase que tiene un método "SendMessage (...)".
Luego puede hacer lo siguiente desde todas partes:
MessageQueue.Current.SendMessage (nuevo MailArrivedMessage (...));
Y, por supuesto, hacer:
MessageQueue.Current.RegisterReceiver (este);
en clases que implementan IMessageReceiver.
fuente
Demasiadas personas colocan objetos que no son seguros para subprocesos en un patrón singleton. He visto ejemplos de un DataContext ( LINQ to SQL ) realizado en un patrón singleton, a pesar de que el DataContext no es seguro para subprocesos y es puramente un objeto de unidad de trabajo.
fuente
Aquí hay una cosa más sobre los singletons que nadie dijo todavía.
En la mayoría de los casos, "singletonity" es un detalle de implementación para alguna clase más que una característica de su interfaz. La inversión del contenedor de control puede ocultar esta característica a los usuarios de la clase; solo necesita marcar su clase como singleton (con
@Singleton
anotaciones en Java, por ejemplo) y listo; IoCC hará el resto. No necesita proporcionar acceso global a su instancia de singleton porque el acceso ya está administrado por IoCC. Por lo tanto, no hay nada malo con IoC Singletons.GoF Singletons en oposición a IoC Singletons se supone que exponen "singletonity" en la interfaz a través del método getInstance () y sufren de todo lo dicho anteriormente.
fuente
Los singletons no son malvados, si los usas adecuadamente y mínimamente . Hay muchos otros buenos patrones de diseño que reemplazan las necesidades de singleton en algún momento (y también dan los mejores resultados). Pero algunos programadores desconocen esos buenos patrones y usan el singleton para todos los casos, lo que hace que el singleton sea malo para ellos.
fuente
En primer lugar, una clase y sus colaboradores deben realizar primero su propósito previsto en lugar de centrarse en los dependientes. La gestión del ciclo de vida (cuando se crean instancias y cuando quedan fuera del alcance) no debe ser parte de la responsabilidad de las clases. La mejor práctica aceptada para esto es crear o configurar un nuevo componente para administrar dependencias mediante la inyección de dependencias.
A menudo, el software se vuelve más complicado, tiene sentido tener múltiples instancias independientes de la clase Singleton con un estado diferente. Confirmar código para simplemente tomar el singleton es incorrecto en tales casos. El uso
Singleton.getInstance()
puede estar bien para sistemas pequeños y simples, pero no funciona / escala cuando se necesita una instancia diferente de la misma clase.Ninguna clase debería considerarse como un singleton, sino que debería ser una aplicación de su uso o de cómo se usa para configurar dependientes. Para que sea rápido y desagradable, esto no importa: solo la codificación dura dice que las rutas de archivos no importan, pero para aplicaciones más grandes, tales dependencias deben ser factorizadas y administradas de manera más apropiada usando DI.
Los problemas que el singleton causa en las pruebas es un síntoma de su caso / entorno de uso único codificado. El conjunto de pruebas y las muchas pruebas son individuales y separan algo que no es compatible con la codificación dura de un singleton.
fuente
Debido a que son básicamente variables globales orientadas a objetos, generalmente puede diseñar sus clases de tal manera que no las necesite.
fuente