¿Los singletons inmutables / sin estado son malos?

12

Últimamente ha habido algún tipo de revolución contra los singletons, pero ¿hay algún problema con ellos si son apátridas?

Sé que el uso excesivo habla y todo ... esto se aplica a todo, no solo a los singletons.

    
pregunta m3th0dman 04.01.2013 - 11:05

4 respuestas

12
  > Are immutable/stateless singletons bad?
  • No si no dependen de otros sistemas externos.
    • Ejemplo: una cadena de caracteres que se escapa de html dentro de una cadena.
    • Motivo: en las pruebas de unidad no es necesario reemplazarlo con un simulador / simulador.
  • Sí si su singleton inmutable / sin estado depende de otros sistemas / servicios externos y si desea realizar la prueba de unidad (pruebas en aislamiento)
    • Ejemplo: un servicio que depende de un servicio web de calculadora de impuestos externa.
    • Motivo: para realizar pruebas de unidad con este Servicio (en forma aislada), debe simular / simular los Sistemas / Servicios externos.

Para obtener más información, consulte the-onion-architecture

  • Singleton-s puede hacer que las pruebas unitarias (de forma aislada) sean más difíciles / imposibles y
  • Las dependencias / acoplamientos ocultos se pueden ver como un problema, como lo explica @yBee

No veo otras razones por las que no uso Singletons.

    
respondido por el k3b 04.01.2013 - 15:54
10

Siempre depende del uso. Creo que la revolución viene del hecho de que cada programador aprende este patrón como el patrón orientado a objetos. La mayoría olvida pensar dónde tiene sentido y dónde no.
Esto, por supuesto, es cierto para cada patrón. Solo con el uso de patrones no creas buen código o buen software.

Si tienes un singleton sin estado, ¿por qué no usar una clase que ofrece solo métodos estáticos (o usar una clase estática)?

Aquí alguna publicación sobre variables globales y singletons en general.

No sería tan estricto como el autor, pero muestra que para la mayoría de los casos en los que crees que necesitas un singleton, realmente no lo necesitas.

    
respondido por el StampedeXV 04.01.2013 - 11:18
7

No hay nada que pueda hacer un singleton sin estado inmutable que una clase estática no pueda.

Simplemente no hay razón para agregar el nivel adicional de complejidad que crea > Instance (), mientras que la simple llamada a un método estático será más clara, más conservadora en términos de recursos y, probablemente, más rápida.

No es que estén equivocados. Es que hay una mejor manera de hacerlo. Hay escenarios en los que los singletons normales ("con estado") son el camino correcto a seguir. Lo malo de singleton es que a menudo se abusa de ellos, con los mismos malos resultados que las variables globales, pero hay casos específicos en los que usar un singleton es simplemente correcto. No hay casos de este tipo para los apátridas.

    
respondido por el SF. 04.01.2013 - 11:30
3

El principal problema con singleton es que oculta las dependencias y el acoplamiento especialmente cuando se usa en un escenario de preocupaciones transversales. Consulte Singletons are Pathological Liars o Porque Singletons are Evil para leer más.

Desde el otro lado, un estado menos singleton, si no se abusa, puede ser útil y mejorar el rendimiento. Considere un ejemplo:

interface Interface
{
    void Method();
}

class StatelessSingleton : Interface
{
    public static readonly StatelessSingleton Instance = new StatelessSingleton();
    private StatelessSingleton() { }

    public void Method() { }
}

class User
{
    public User(Interface i) { /* ... */ }
}

Aquí, StatelessSingleton actúa como implementación predeterminada de la Interfaz y se coloca en el constructor del Usuario. No hay acoplamiento codificado y dependencias ocultas. No podemos utilizar una clase estática debido a la interfaz subyacente, pero no hay razón para crear más de una instancia de un valor predeterminado. Es por eso que un singleton sin estado parece ser una opción apropiada.

Sin embargo, tal vez deberíamos usar otro patrón para una implementación predeterminada:

class Implementation : Interface
{
    private readonly Action _method;

    public Implementation()
    {
        _method = new Action(() => { /* default */ });
    }

    public Implementation(Action custom)
    {
        _method = custom;
    }

    public void Method()
    {
        _method();
    }
}

Alcanza el rendimiento con respecto a StatelessSingleton pero constituye una implementación genérica de la Interfaz. Una solución similar es utilizada por la interfaz IProgress .

Nuevamente, ¿por qué permitir crear más de una implementación del comportamiento predeterminado? Sin embargo, podemos combinar los dos:

class Implementation : Interface
{
    public readonly Implementation Default = new Implementation();

    private readonly Action _method;

    private Implementation()
    {
        _method = new Action(() => { /* default */ });
    }

    public Implementation(Action custom)
    {
        _method = custom;
    }

    public void Method()
    {
        _method();
    }
}

En conclusión, creo que hay lugares (como los valores predeterminados descritos) donde Singletons son útiles. La definición principal de Singleton establece que no permite crear más de una instancia de una clase. Es como la energía nuclear. Puede producir una energía o una bomba. Depende de lo humano.

    
respondido por el yBee 02.08.2013 - 10:51

Lea otras preguntas en las etiquetas