C'è qualcosa come un Singleton polimorfo?

6

Ho un oggetto caricatore di risorse che carica oggetti dal disco o da un archivio ZIP, a seconda della piattaforma.

Ha uno stato (ad esempio il percorso della directory o dell'archivio ZIP, e possibilmente un po 'di cache in futuro), quindi deve essere una singola istanza.

Quindi normalmente, un Singleton farebbe. Ma il mio problema è che questo caricatore di risorse ha implementazioni multiple, di cui uno viene scelto durante l'inizializzazione. Quindi non trasformare il caricatore di risorse in Singleton.

Tutto quello che posso pensare è di avere un Singleton che contiene un riferimento al caricatore di risorse singolo. Ma non c'è uno schema migliore per questo?

    
posta futlib 19.01.2013 - 18:57
fonte

4 risposte

19

Quello che vuoi sembra un buon caso per il modello di fabbrica . Scrivi qualcosa come:

class LoaderFactory {
  public Loader getLoader() {
    if (environment1) return ZipLoader.getInstance();
    else if (environment2) return DiskLoader.getInstance();
    else return SomeOtherLoader.getInstance();
  }
}

Ogni tipo di classe Loader è un singleton e ognuno dovrebbe implementare l'interfaccia Loader . Il tuo LoaderFactory esegue la logica che determina quale tipo è appropriato restituire.

    
risposta data 19.01.2013 - 19:22
fonte
2

Questo non ha nulla a che fare con il pattern Singleton.

Ciò di cui hai bisogno è una specie di tipo di gestore delle risorse che registra gli oggetti delle fabbriche, uno per ciascun tipo di risorsa che desideri sia in grado di fornire. Ogni oggetto factory saprebbe come caricare il tipo di risorsa associato.

Quindi, quando si desidera una risorsa, si utilizza una funzione per ottenere la risorsa da un'istanza del gestore risorse, che troverà la risorsa già caricata per voi o richiederà il factory specifico del tipo di risorsa che possiede per caricarlo.

L'interfaccia sarebbe simile a questa (ma in realtà dipende dal tuo contesto alla fine):

class ResourceManager
{
public:

    template<ResourceType>
    void add_factory( std::shared_ptr<ResourceFactory<ResourceType>> factory );

    template<Resourcetype>
    std::shared_ptr<ResourceType> get(); // will look into registered factories and provide a resource instance if it   

};

Questo è un modo classico per gestire le risorse raccolte in un oggetto.

Una volta che si ha un tipo di questo tipo (una classe ResourceManager per esempio) funzionante, è facile farlo (o no, come altri suggeriscono) Singleton. Non lo consiglio però.

Non è la tua classe che è polimorfica, è il tipo di risorsa.

Un modo migliore, il più delle volte, è di passare un riferimento all'istanza del gestore risorse in funzioni e tipi che ne hanno bisogno. Ci sono casi in cui renderlo un singleton sarebbe meglio, ma è molto raro.

    
risposta data 19.01.2013 - 19:10
fonte
1

Tutte le risposte sono ben definite. Voglio solo stupire che il polimorfismo e il singleton sono quelli che potreste chiamare preoccupazioni ortogonali. Il polimorfismo è più di un concetto e il modo in cui realizziamo tale concetto, mentre Singleton sta definendo un modello e sfruttando il concetto di polimorfismo per casi d'uso come quello che si presenta.

    
risposta data 20.01.2013 - 00:44
fonte
0

Sembra che tu abbia un caso d'uso per un Inversion of Control (IoC) Container - usano quello che viene chiamato < a href="http://en.wikipedia.org/wiki/Dependency_injection"> Dipendenza dell'iniezione (DI) per creare / inizializzare istanze di oggetti e collegare le cose insieme per l'operazione.

( Questo articolo sui contenitori IoC e DI potrebbe non essere la migliore introduzione ai contenitori IoC (non riesco a sembrare per trovare uno buono al momento), ma è una buona lettura.)

Da quello che ho letto sono simili alle fabbriche e sono utili per creare istanze temporanee in fase di esecuzione.

Un post SO che potrebbe essere di interesse: Iniezione delle dipendenze rispetto al modello di fabbrica

Non sono sicuro di come funzionerebbe con il recupero di una singola istanza, non ne ho mai usata una prima, ne ho solo letto.

    
risposta data 24.01.2013 - 17:23
fonte

Leggi altre domande sui tag