Nascondi o Mostra singleton?

4

Singleton è uno schema comune implementato in entrambe le librerie native di .NET e Java. Lo vedrai come tale:

C #: MyClass.Instance

Java: MyClass.getInstance()

La domanda è: durante la scrittura delle API, è meglio esporre il singleton attraverso una proprietà o un getter, o dovrei nasconderlo il più possibile?

Ecco le alternative a scopo illustrativo:

Exposed (C #):

private static MyClass instance;
public static MyClass Instance
{
    get {
        if (instance == null)
            instance = new MyClass();
        return instance;
    }
}

public void PerformOperation() { ... }

Nascosto (C #):

private static MyClass instance;

public static void PerformOperation()
{
    if (instance == null)
    {
        instance = new MyClass();
    }
    ...
}

Modifica Sembra esserci un numero di detrattori del design Singleton. Grande! Per favore dimmi perché e qual è l'alternativa migliore. Ecco il mio scenario:

Tutta la mia applicazione utilizza un logger (log4net / log4j). Ogni volta che il programma ha qualcosa da registrare, utilizza la classe Logger (ad esempio Logger.Instance.Warn(...) o Logger.Instance.Error(...) ecc. Dovrei usare Logger.Warn(...) o Logger.Warn(...) invece?

Se hai un'alternativa ai singleton che rispondono alla mia preoccupazione, per favore scrivi una risposta per questo. Grazie:)

    
posta Sinker 01.07.2013 - 13:56
fonte

2 risposte

9

Penso che nascondere Singleton sia una cattiva idea. Se non hai un modo per ottenere un riferimento all'istanza creata tramite un metodo getInstance() , come lo farai considerando che le classi Singleton non hanno costruttori public ? Non c'è modo di ottenere quel riferimento. Ciò significa che se decidi di "nascondere" Signbleton, la tua unica opzione è quella di verificare in ogni public static il metodo della classe Signletone se l'istanza è già stata istanziata e in caso contrario, fallo. Quindi il tuo codice diventa qualcosa del genere:

class BadSingletone {
    private static MyClass instance;

    public static void PerformOperation()
    {
        if (instance == null) { instance = new MyClass(); }
        ...
    }

        public static void PerformSomeOtherOperation()
    {
        if (instance == null) { instance = new MyClass(); }
        ...
    }

    public static void PerformYetAnotherOperation()
    {
        if (instance == null) { instance = new MyClass(); }
        ...
    }
}

disseminato di tutti quei controlli di istanziazione. Ovviamente puoi incapsulare il controllo in una funzione separata, ma dovrai chiamarlo nuovamente in ogni funzione public static della classe. E se dimenticassi accidentalmente di includerlo in una delle funzioni? Gli utenti della classe non ne saranno contenti.

Quindi, a mio parere, nascondere Singleton non ha senso: ti fa sporcare il tuo codice con controlli non necessari.

    
risposta data 01.07.2013 - 14:21
fonte
1

Tecnicamente, non credo che sia ancora considerato un modello singleton a meno che non esporti l'istanza ad altre classi. È solo un membro statico privato. Detto questo, in generale minore è lo scopo di una variabile, meglio è. Se altre classi non ne hanno bisogno, non condividerle. Tuttavia, nella maggior parte dei casi sarà molto più semplice solo istanziare il membro statico alla dichiarazione invece di controllare ovunque se è già stato istanziato.

    
risposta data 01.07.2013 - 16:14
fonte

Leggi altre domande sui tag