secuencia patrones patron explicacion ejercicios ejemplos diseño diagrama conexion singleton design-patterns

patrones - Alternativas para el patrón singleton?



patrones de diseño java ejemplos (4)

He sido desarrollador web desde hace algún tiempo utilizando ASP.NET y C #, quiero probar y aumentar mis habilidades mediante el uso de las mejores prácticas.

Tengo un sitio web Quiero cargar la configuración una vez, y solo hacer referencia donde sea que la necesite. Así que investigué y el 50% de los desarrolladores parecen estar usando el patrón singleton para hacer esto. Y el otro 50% de los desarrolladores son ant-singleton. Todos odian a los solteros. Recomiendan la inyección de dependencia.

¿Por qué los singleton son malos? ¿Cuál es la mejor práctica para cargar configuraciones de sitios web? ¿Deberían cargarse solo una vez y hacer referencia a ellos cuando sea necesario? ¿Cómo podría hacer esto con la inyección de dependencia (soy nuevo en esto)? ¿Hay alguna muestra que alguien pueda recomendar para mi escenario? Y también me gustaría ver algún código de prueba unitaria para esto (para mi escenario).

Gracias Brendan


En general, evito los singletons porque dificultan la prueba unitaria de su aplicación. Los Singletons son difíciles de simular para las pruebas unitarias precisamente por su naturaleza: siempre obtendrá el mismo, no uno que pueda configurar fácilmente para una prueba unitaria. Sin embargo, la configuración de los datos de configuración fuertemente tipados es una excepción. Por lo general, los datos de configuración son relativamente estáticos y la alternativa implica escribir una buena cantidad de código para evitar las clases estáticas que el marco proporciona para acceder a web.config de todos modos.

Hay un par de maneras diferentes de usarlo que aún le permitirán probar su aplicación. Una forma (quizás en ambos sentidos, si su singleton no lee perezosamente la aplicación.cofnig) es tener un archivo app.config predeterminado en su proyecto de prueba unitario que proporcione los valores predeterminados requeridos para sus pruebas. Puede usar la reflexión para reemplazar cualquier valor específico según sea necesario en las pruebas de su unidad. Normalmente, configuro un método privado que permite que se elimine la instancia de singleton privada en la configuración de prueba si realizo cambios para pruebas particulares.

Otra forma es no usar el singleton directamente, sino crear una interfaz para que implemente la clase singleton. Puede utilizar la inyección manual de la interfaz, por defecto a la instancia singleton si el valor suministrado es nulo. Esto le permite crear una instancia simulada que puede pasar a la clase bajo prueba para sus pruebas, pero en su código real use la instancia singleton. Esencialmente, cada clase que lo necesita mantiene una referencia privada a la instancia de singleton y la usa. Me gusta de esta manera un poco mejor, pero dado que se creará el singleton, es posible que aún necesite el archivo app.config predeterminado, a menos que todos los valores estén cargados de forma laxa.

public class Foo { private IAppConfiguration Configuration { get; set; } public Foo() : this(null) { } public Foo( IAppConfiguration config ) { this.Configuration = config ?? AppConfiguration.Instance; } public void Bar() { var value = this.Config.SomeMaximum; ... } }



Los patrones de diseño pueden ser cosas increíbles. Desafortunadamente, el singleton parece sobresalir como un pulgar dolorido y en muchos casos puede considerarse un antipatrón (promueve malas prácticas). Bizarely, la mayoría de los desarrolladores solo conocerán un patrón de diseño, y ese es el singleton.

Idealmente, su configuración debe ser una variable miembro en una ubicación de alto nivel, por ejemplo, el objeto de la aplicación que posee las páginas web que está generando. Las páginas pueden solicitar a la aplicación la configuración o la aplicación puede pasar las configuraciones a medida que se construyen las páginas.


Una forma de abordar este problema es eliminarlo como un problema DAL.

Cualquiera que sea la clase / página web, etc. que necesite para usar configuraciones de configuración, debe declarar una dependencia en un IConfigSettingsService (factory / repository / whatever-you-like-to-call-them).

private IConfigSettingsService _configSettingsService; public WebPage(IConfigSettingsService configSettingsService) { _configSettingsService = configSettingsService; }

Entonces tu clase obtendría configuraciones como esta:

ConfigSettings _configSettings = _configSettingsService.GetTheOnlySettings();

la implementación de ConfigSettingsService tendría una dependencia que es la clase Dal. ¿Cómo poblaría Dal el objeto ConfigSettings? A quien le importa.

  • Tal vez llenaría ConfigSettings desde una base de datos o archivo .config xml, cada vez.

  • Tal vez lo haga la primera vez, pero luego complete un _configSettings estático para llamadas posteriores.

  • Tal vez obtendría la configuración de Redis. Si algo indica que la configuración ha cambiado, entonces el dal, o algo externo, puede actualizar Redis. (Este enfoque será útil si tiene más de una aplicación usando la configuración.

Lo que sea que haga, su única dependencia es una interfaz de servicio no única. Eso es muy fácil de burlarse. En sus pruebas, puede hacer que devuelva ConfigSettings con lo que quiera en él).

En realidad, es más probable que MyPageBase tenga la dependencia IConfigSettingsService, pero también podría ser un servicio web, un servicio de Windows, MVC somewhatsit o todo lo anterior.