L'approccio semplice è quello di rendere la cosa che invece era Singleton<T>
globale T
. Anche i globali hanno problemi, ma non rappresentano un sacco di lavoro extra e codice boilerplate per imporre un banale vincolo. Questa è sostanzialmente l'unica soluzione che non coinvolgerà (potenzialmente) il contatto con il costruttore dell'entità.
L'approccio più difficile, ma forse migliore, è passare le tue dipendenze dove ne hai bisogno . Sì, ciò potrebbe comportare il passaggio Window *
di un gruppo di oggetti (come la tua entità) in un modo che sembra grossolano. Il fatto che appaia disgustoso dovrebbe dirti qualcosa: il tuo design potrebbe essere disgustoso.
Il motivo per cui ciò è più difficile (oltre a comportare una maggiore digitazione) è che questo spesso porta a refactoring delle tue interfacce in modo che la cosa che "hai bisogno" di passare sia necessaria da un numero inferiore di classi a livello foglia. Questo rende un sacco di bruttezza insita nel passare il tuo renderer a tutto ciò che va via, e migliora anche la manutenibilità generale del tuo codice riducendo la quantità di dipendenze e accoppiamento, la misura di cui hai reso molto ovvio prendendo le dipendenze come parametri . Quando le dipendenze erano singole o globali, era meno ovvio quanto fossero interconnessi i tuoi sistemi.
Ma è potenzialmente un'impresa importante . Farlo su un sistema dopo il fatto può essere decisamente doloroso. Potrebbe essere molto più pragmatico per te lasciare semplicemente il tuo sistema da solo, con il singleton, per ora (specialmente se stai cercando di spedire un gioco che altrimenti funziona bene, i giocatori non si preoccuperanno in genere se hai un singleton o quattro in là).
Se vuoi provare a farlo con il tuo progetto esistente, potresti dover pubblicare molti più dettagli sulla tua attuale implementazione in quanto non esiste davvero un elenco di controllo generale per apportare queste modifiche. O vieni a discuterne chat .
Da quello che hai pubblicato, penso che un grande passo nella direzione "no singleton" sarebbe quello di evitare la necessità per le tue entità di avere accesso alla finestra o alla vista. Suggerisce che si disegnano da soli, e con lo sprite cercarono l'entità. non è necessario che le entità si disegnino da sole . È possibile adottare una metodologia in cui le entità contengono solo le informazioni che consentirebberoessi devono essere disegnati da un sistema esterno (che ha la finestra e visualizzare i riferimenti). L'entità espone semplicemente la sua posizione e lo sprite che dovrebbe usare (o qualche tipo di riferimento a detto sprite, se si desidera memorizzare nella cache gli sprite effettivi nel renderer stesso per evitare di avere istanze duplicate). Al renderer viene semplicemente detto di disegnare un particolare elenco di entità, attraverso il quale scorre, legge i dati e usa il suo oggetto finestra tenuto internamente per chiamaredraw