2009-09-19 30 views
20

Actualmente estoy muy interesado en este "patrón de diseño". Aunque no estoy seguro si hay caídas usando esta estricta implementación de estado global. Entonces, ¿cuándo piensas no practicar singleton en una aplicación?Patrón de diseño singleton: escollos

+0

[Aquí] (https://www.michaelsafyan.com/tech/design/patterns/singleton) es una buena lectura en singleton que es un antipatrón. – RBT

Respuesta

35

Singleton es generalmente una mala idea si está haciendo pruebas unitarias, y generalmente es una mala idea no hacer pruebas unitarias (o BDD o pruebas de aceptación).

Hacer que los objetos tengan estado global significa que las pruebas de la unidad que escribe con estos objetos se aislarán y separarán entre sí. En cambio, tendrá que preocuparse por restablecer el estado de cada prueba y créame ... eso nunca se hace el 100% del tiempo. Si no restablece el estado global, entonces comienza a obtener errores muy extraños y difíciles de depurar en sus pruebas que pierden tiempo.

El estado global también aumenta el acoplamiento en el código y dificulta la refactorización.

El método ideal sería utilizar un contenedor IoC/DI (Spring, Guice, etc.) para solicitar objetos. Estos contenedores a menudo tienen formas de hacer que los objetos aparezcan como 'Singletons', pero también tienen formas de modificar ese comportamiento según la situación (es decir, pruebas unitarias frente a su código de dominio).

Todo esto depende del tamaño de su problema, por supuesto. Si está pirateando un equipo de prueba de 4 clases para probar algo, entonces use un Singleton. Sin embargo, tan pronto como ese proyecto cobre vida y se vuelva más grande y más complejo, refactorizar el Singleton.

+0

¿Quiere decir que los singleton son * nunca * elegibles para el uso en proyectos reales (y detectar un singleton en un proyecto real equivale automáticamente al olor del código independientemente del caso de uso)? – Pacerier

+0

Huelo un troll ... –

+0

Abstenerse de olfatear a ti mismo entonces. Su respuesta sugiere que los singletons solo se usan para el código de "fase inicial" y deben tenerse en cuenta en todos los proyectos maduros que crecen. ¿Quiere decir que los singletons nunca son elegibles para el uso en estos proyectos, o hay casos de uso válidos? – Pacerier

3

Usaría un Singleton muy raramente. Debido a su naturaleza (objetos estáticos, globales) son difíciles de usar en la prueba de unidad de su código. Termina necesitando sincronizar o crear algunos mecanismos de reinicialización para que pueda obtener una versión nueva para cada prueba unitaria. Hay casos que tienen sentido, por ejemplo, una clase de configuración global, pero son mucho menos de lo que parecen creer las personas nuevas en singleton. Sé que pasé por una fase en la que vi aplicaciones del patrón singleton en todas partes. Ahora lo evito donde puedo y lo deshago a través de la refactorización en mi código, ya que me encuentro con una implementación innecesaria.

7

Además de los problemas de prueba y diseño mencionados en otras publicaciones, existen problemas con Singletons y classloaders. Los singletons no son realmente "únicos" por JVM o aplicación; lo logran a través de la propiedad estática, lo que realmente significa que hay uno por clase. Si hay varios cargadores de clases, como en la mayoría de los servidores de aplicaciones, cada aplicación por separado obtiene un nuevo cargador de clases, incluso se utilizan varios niveles de cargadores de clases en EJB. Se carga una instancia de singleton por cargador de clases, lo que, dependiendo de lo que esté haciendo con el singleton, puede no producir los resultados que espera.

+1

@Nate, esto suena interesante, ¿podría darme un ejemplo concreto? – eric2323223

+0

¿Existen fuentes autorizadas para su reclamo? ¿Por qué las instancias separadas de JRE no deberían usar instancias separadas de singletons? – Pacerier

+0

@Pacerier http://www.oracle.com/technetwork/articles/java/singleton-1577166.html JRE separados utilizando instancias de singleton separadas es el caso esperado; el problema es que un solo JRE puede tener varios cargadores de clases y, por lo tanto, varias instancias de singleton. . – Nate

18

Google Tech Talks tuvo hace algún tiempo una buena presentación sobre Global State and Singletons. El patrón de singleton estático es malo, porque causa efectos secundarios no deseados y hace que el código no sea comprobable. Static singleton es la versión OO de las variables globales.

La solución es simplemente crea una instancia del objeto y pásala a sus usuarios a través de la inyección de dependencia. Los marcos DI, como Guice, facilitan la definición del buen tipo de singleton (en Guice simplemente anota una clase con @Singleton). Hubo un Tech Talk similar llamado Don't Look For Things! que discutió DI más.