Senza usare Singletons, qual è un buon modo per gestire una risorsa globale? [duplicare]

0

A differenza di molte librerie SDL e OpenGL sono progettate per fornire risorse globali; puoi accedervi in qualsiasi momento da qualsiasi classe. Ci sono giustificazioni per questo: sono scritte in C, pensate per essere prontamente multipiattaforma e progettate per essere veloci.

Tuttavia non sono orientati agli oggetti, e lo stato globale dovrebbe essere normalmente un'idea molto cattiva. Aggiunge drammaticamente il numero di ingressi a ogni funzione del tuo codice.

Diciamo che stai lavorando in C ++ o qualche altro linguaggio orientato agli oggetti con una di queste librerie. Sai di quale funzionalità hai bisogno. A quel punto non è una buona idea incapsulare ciò che ti serve nelle classi X e Y e dire "ogni volta che hai bisogno di lavorare con questa libreria, usa X e Y"?

Ad esempio, con SDL, sembra una buona idea avere una classe che chiami SDL_Init nel costruttore e pulisca tutto nel distruttore. Questa classe manager ti consente solo di creare finestre e renderer mentre SDL è attivo.

Una buona causa per un singleton forse? Preferirei di no. Il Blog Test di Google fornisce un buon esempio di un caso contro singleton: link

Quindi in realtà le mie domande sono 1) se incapsulare parte di una libreria è una buona idea o pura follia e 2) come affrontare la gestione delle risorse globali senza singleton.

EDIT: la risposta di Paul K qui fornisce un'introduzione davvero valida e concisa all'iniezione di dipendenza, che elimina la necessità di singleton. Tuttavia non è ancora chiaro come gestire lo stato che è sfortunatamente reso globale da una libreria come OpenGL o SDL. L'ampio stato globale fornito da queste librerie non può essere facilmente passato per riferimento a meno che non sia raccolto insieme e gestito da una classe wrapper. Anche una volta fatto, il client può comunque utilizzare direttamente la libreria.

    
posta matt_rule 05.04.2016 - 14:28
fonte

2 risposte

2

Una buona alternativa ai singleton sta usando Dependency Injection come descritto nella risposta di Paul K qui . Crea e inizializza una classe con lo scope necessario più alto, quindi passala per riferimento.

Quando si tratta di risorse / risorse esistenti a livello globale, la mia soluzione sarebbe: 1) Determinare quali parti dello stato globale sono necessarie. 2) Incapsularli in un insieme di classi wrapper. 3) Dipendenza Iniettare queste classi.

AFAIK non esiste un modo per impedire al client di accedere direttamente alla risorsa.

    
risposta data 05.04.2016 - 15:33
fonte
0

Una delle cose che mi ha infastidito a lungo nel dibattito attorno al modello Singleton è che quasi nessuno guarda al modello di design originale di GoF. Stanno parlando di una superficiale semplificazione del modello. Penso che questo sia piuttosto irrispettoso per gli autori di un libro che è probabilmente uno dei testi più influenti nell'ingegneria del software di sempre. Lo consiglio vivamente come primer per il design OO.

Ciò che la maggior parte della gente perde se nel testo originale, se si guarda il codice di esempio la definizione di Singleton è astratta. L'idea è che è possibile creare diverse versioni dell'oggetto Singleton reale e utilizzare la configurazione per caricare quello desiderato in fase di runtime. Suona familiare? Dovrebbe perché è essenzialmente un proto-DI in un ambito molto ristretto.

L'articolo di cui fai riferimento attacca Singletons sulla base del fatto che sono uno stato globale. Lo stato condiviso è uno stato condiviso problematico e disponibile a livello globale ancora di più. Si dovrebbe assolutamente evitare lo stato condiviso il più possibile. Non sono convinto che sia sempre possibile evitare e se è necessario condividere lo stato, il modello Singleton è la strategia per incapsulare e gestire quella condivisione di stato. Se stai usando DI per iniettare lo stato condiviso su tutto il tuo programma, hai ancora uno stato condiviso. DI non è una soluzione per evitare lo stato condiviso. È una soluzione per evitare l'accoppiamento e se si costruisce il Singleton come descritto nei modelli GoF, si evita anche l'accoppiamento.

    
risposta data 05.04.2016 - 17:59
fonte

Leggi altre domande sui tag