A abordagem simples é criar o que antes era Singleton<T>
global T
. Os Globals também têm problemas, mas eles não representam um monte de código extra de trabalho e clichê para impor uma restrição trivial. Essa é basicamente a única solução que não envolve (potencialmente) tocar no construtor da entidade.
A abordagem mais difícil, mas possivelmente melhor, é passar suas dependências para onde você precisar . Sim, isso pode envolver a passagem de Window *
para um monte de objetos (como sua entidade) de uma maneira que parece grosseira. O fato de parecer grosseiro deve lhe dizer uma coisa: seu design pode ser grosseiro.
A razão pela qual isso é mais difícil (além de envolver mais digitação) é que isso geralmente leva à refatoração de suas interfaces, para que o que você "precisa" passar seja necessário por menos classes no nível da folha. Isso faz com que muita feiura seja inerente ao passar seu renderizador para que tudo desapareça e também melhora a manutenção geral do seu código, reduzindo a quantidade de dependências e acoplamentos, cuja extensão você ficou muito óbvia ao considerar as dependências como parâmetros. . Quando as dependências eram singletons ou globais, era menos óbvio a interconexão de seus sistemas.
Mas é potencialmente uma grande empresa. Fazer isso em um sistema após o fato pode ser absolutamente doloroso. Pode ser muito mais pragmático para você simplesmente deixar seu sistema em paz, com o singleton, por enquanto (especialmente se você estiver tentando realmente lançar um jogo que, de outra forma, funciona muito bem; os jogadores geralmente não vão se importar se você tiver um singleton ou quatro lá).
Se você quiser tentar fazer isso com o design existente, talvez seja necessário postar muito mais detalhes sobre sua implementação atual, pois não há realmente uma lista de verificação geral para fazer essas alterações. Ou venha discuti-lo no chat .
Pelo que você postou, acho que um grande passo na direção "sem singleton" seria evitar a necessidade de suas entidades terem acesso à janela ou exibição. Isso sugere que eles se desenham, e você não precisa que as entidades se desenhem . Você pode adotar uma metodologia em que as entidades contenham apenas as informações que permitiriameles devem ser desenhados por algum sistema externo (que possui as referências de janela e exibição). A entidade apenas expõe sua posição e o sprite que deve usar (ou algum tipo de referência ao referido sprite, se você deseja armazenar em cache os sprites reais no próprio renderizador para evitar instâncias duplicadas). O renderizador é simplesmente instruído a desenhar uma lista específica de entidades, através da qual ele percorre, lê os dados e usa seu objeto de janela mantido internamente para chamar draw
com o sprite procurado pela entidade.