2012-07-02 12 views

Respuesta

47

Prueba

Una de las razones es que los únicos que no son fáciles de manejar con pruebas unitarias. No puede controlar la creación de instancias y, por su propia naturaleza, puede retener el estado en todas las invocaciones.

Por esa razón, el principio de dependency injection es popular. Cada clase se inyecta (configura) con las clases que necesitan para funcionar (en lugar de derivar a través de accesadores singleton) y así las pruebas pueden controlar qué instancias de clase dependientes usar (y proporcionar simulaciones si es necesario).

Los marcos como Spring controlarán el ciclo de vida de sus objetos y a menudo crearán singletons, pero estos objetos se inyectan en sus objetos dependientes por el marco. Por lo tanto, la base de código en sí misma no trata los objetos como singletons.

p. Ej. en lugar de esto (por ejemplo)

public class Portfolio { 
    private Calculator calc = Calculator.getCalculator(); 
} 

que inyectaría la calculadora:

public class Portfolio { 
    public Portfolio(Calculator c) { 
     this.calc = c; 
    } 
} 

Por lo tanto el objeto Portfolio No sabe/cuidado acerca de cómo existen muchos casos de la Calculator. Las pruebas pueden inyectar un dummy Calculator que facilita las pruebas.

concurrencia

Por limitación a una instancia de un objeto, las opciones para el roscado son limitados. El acceso al objeto singleton puede tener que estar protegido (por ejemplo, a través de la sincronización). Si puede mantener varias instancias de esos objetos, puede adaptar el número de instancias a los hilos que tiene en ejecución y aumentar las capacidades simultáneas de su base de código.

+2

Entonces, ¿cómo las personas que usan singleton se ocupan de "Prueba" y " Problemas de concurrencia? – Pacerier

+0

Con alguna dificultad. Herramientas como PowerMock pueden proporcionar medios para anular métodos singleton, pero son herramientas complejas que recurren a la manipulación de códigos byte –

21

Mi opinión personal es que viola el principio de responsabilidad única. Los objetos Singleton son responsables tanto de su propósito como de controlar el número de instancias que producen, lo cual creo que es incorrecto.

Es por eso que muchas personas delegan el control en un objeto de fábrica.

+0

Creo que eso hace que [la interpretación de] SRP sea sospechosa. –

+0

¿De qué manera es sospechoso? – MikePatel

+0

Sospechoso en que esto claramente no es algo que está mal con Singletons, pero la interpretación de SRP indica que sí lo está. SRP (o esta interpretación) parece ser el culpable. –

6

Hay muchos requisitos que pueda tener en el producto único:

  1. inicialización perezosa;
  2. eliminación adecuada;
  3. alcance (uno por hilo, por ejemplo).

Típicamente, también, tendrá un montón de hijos únicos en su aplicación, y el patrón deSingleton no permite código reutilizable. Por lo tanto, si desea implementar todas estas inquietudes para todos sus singletons, inmediatamente verá su anti-pattern calidad.

7

Los Singletons como tales no son necesariamente un anti-patrón, pero tienen solo unos pocos beneficios y se convierten en antipatrón cuando se usan incorrectamente (lo que sucede a menudo).

A menudo, los singletons no son singleton en absoluto, sino "variables globales disfrazadas". Además, a menudo se usan cuando la propiedad "única instancia" no es realmente una ventaja. (que de nuevo se equilibra por el hecho de que muchas veces la implementación es incorrecta al mismo tiempo).

Además de eso, pueden ser difíciles de implementar teniendo en cuenta el multihilo (a menudo se hace incorrectamente o de manera ineficiente), y pierden la mayoría de sus beneficios si desea controlar su creación de instancias.

Si desea tener control sobre la creación de instancias, debe hacerlo a mano en algún momento temprano en el programa, pero también podría simplemente crear una instancia de un objeto normal y pasarlo a continuación.
Si el orden de destrucción es preocupante, debe implementarlo manualmente también. Un único objeto automático en la función principal es mucho más limpio y fácil.

10

[Mutable] Singleton es un anti-patrón de un anti-patrón.

El antipatrón subyacente significativo es el estado global (o el estado ambiente). Con estado global, tiene un gran blog de dependencia en su programa. Esto afecta las pruebas, pero eso es solo una parte de las consecuencias de la mala programación.

En capas, Singleton agrega un nivel completamente innecesario de complejidad a la simple declaración de campos static mutables.

+2

Mutable static los campos sufren el mismo problema exacto, es un estado global. No veo cómo usar campos estáticos es mejor que un singleton. ¿Alguna información sobre eso? –

+2

@JuanMendes Como digo, las estáticas mutables directas son mejores que las estáticas mutables simples porque no tienen la complejidad inútil. –

+0

Debo revisar las respuestas mejor antes de dejar un comentario. 100% de acuerdo con usted Básicamente es un eufemismo para el estado global, por lo que al llamarlo campos estáticos al menos no intenta embellecerlo. –

3

Extraño. Parece que la implementación incorrecta de un Singleton es un "antipatrón", no el Singleton en sí mismo.

Creo que hemos olvidado que cada programa tiene que comenzar en alguna parte. Tiene que haber una implementación concreta de cada abstracción, y finalmente cada dependencia se resolverá eventualmente, o su aplicación no sería de mucha utilidad.

La mayoría de los marcos DI permiten crear instancias de una clase como Singleton, simplemente se encarga de eso. Si elige hacer DI usted mismo, inyectar un singleton no es un problema. También se puede probar un Singleton IS, y si está usando DI para inyectarlo, no hace que una clase sea inestable.

IMO, como cualquier otro patrón (incluyendo DI y IoC) es una herramienta. A veces se ajusta, otras veces no.

Cuestiones relacionadas