I maledetti immutabili / apolidi sono cattivi?

12

Ultimamente c'è stata una sorta di rivoluzione contro i singleton, ma c'è qualcosa di sbagliato in loro se sono apolidi?

Conosco le discussioni sull'uso eccessivo e tutto ... questo vale per tutto, non solo per i singleton.

    
posta m3th0dman 04.01.2013 - 11:05
fonte

4 risposte

12
  > Are immutable/stateless singletons bad?
  • No se non dipendono da altri sistemi esterni.
    • Esempio: una Stringutility che sfugge a html all'interno di una stringa.
    • Motivo: nelle domande non è necessario sostituirlo con un simulatore / simulatore.
  • se il tuo singleton immutabile / stateless dipende da altri sistemi / servizi esterni e se vuoi eseguire l'unittesting (testing in Isolation)
    • Esempio: un servizio che dipende da un servizio di calcolo delle imposte esterno-Web.
    • Motivo: per poter effettuare la disattivazione di questo Servizio (in isolamento) è necessario simulare / prendere in giro i Sistemi / Servizi esterni.

Per maggiori dettagli vedi the-onion-architecture

  • Singleton-s può rendere unit-testing (in isolamento) più difficile / impossibile e
  • dipendenze nascoste / accoppiamento può essere visto come un problema come spiegato da @yBee

Non vedo altri motivi per non utilizzare Singletons.

    
risposta data 04.01.2013 - 15:54
fonte
10

Dipende sempre dall'utilizzo. Penso che la rivoluzione derivi dal fatto che ogni programmatore impara questo modello come il modello orientato agli oggetti. La maggior parte dimentica di pensare a dove ha senso e dove no.
Questo, naturalmente, è vero per ogni modello. Semplicemente usando i pattern non crei un buon codice o un buon software.

Se hai un singleton stateless, perché non usare una classe che offre solo metodi statici (o usa una classe statica)?

Qui alcuni post riguardanti variabili globali e singleton in generale.

Non sarei rigoroso come l'autore, ma mostra che per la maggior parte dei casi in cui pensi di aver bisogno di un singleton, non ne hai davvero bisogno.

    
risposta data 04.01.2013 - 11:18
fonte
7

Non c'è nulla che un singleton stateless immutabile possa fare che una classe statica non possa fare.

Semplicemente non c'è motivo di aggiungere il livello extra di complessità che - > Instance () crea, mentre la semplice chiamata a un metodo statico sarà più chiara, più conservativa in termini di risorse e probabilmente più veloce.

Non è che si sbagliano. È che c'è un modo migliore per farlo. Ci sono scenari in cui i singleton normali ("stateful") sono la strada giusta da percorrere. Il male con singleton è che sono spesso abusati, con gli stessi cattivi risultati delle variabili globali, ma ci sono casi specifici in cui l'uso di un singleton è semplicemente corretto. Non ci sono casi simili per gli apolidi.

    
risposta data 04.01.2013 - 11:30
fonte
3

Il problema principale con Singleton è che nasconde dipendenze e accoppiamenti soprattutto se usato in uno scenario di preoccupazioni trasversali. Vedi Singletons sono bugiardi patologici o Perché Singletons are Evil per ulteriori letture.

Dall'altro lato, uno stato meno singleton, se non abusato, può essere utile e migliorare le prestazioni. Considera un esempio:

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) { /* ... */ }
}

Qui StatelessSingleton funge da implementazione predefinita dell'interfaccia e viene inserito nel costruttore User. Non vi è alcun accoppiamento hardcoded e dipendenze hiden. Non siamo in grado di utilizzare una classe statica a causa dell'interfaccia sottostante, ma non vi è alcun motivo per creare più di un'istanza di un valore predefinito. Ecco perché un singleton apolide sembra essere una scelta appropriata.

Tuttavia, forse dovremmo usare un altro modello per un'implementazione predefinita:

class Implementation : Interface
{
    private readonly Action _method;

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

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

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

Colpisce le prestazioni rispetto a StatelessSingleton ma costituisce un'implementazione generica dell'interfaccia. Una soluzione simile viene utilizzata dall'interfaccia IProgress .

Ancora una volta, perché consentire di creare più di un'implementazione del comportamento predefinito? Eppure possiamo combinare i due:

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();
    }
}

In conclusione, credo che ci siano luoghi (come valori predefiniti illustrati) in cui Singletons sono utili. La definizione principale di Singleton afferma che non consentire di creare più di un'istanza di una classe. È come l'energia nucleare. Può produrre energia o una bomba. Dipende dall'essere umano.

    
risposta data 02.08.2013 - 10:51
fonte