El enfoque simple es simplemente hacer lo que solía ser Singleton<T>
global en su T
lugar. Los globales también tienen problemas, pero no representan un montón de trabajo extra y código repetitivo para imponer una restricción trivial. Esta es básicamente la única solución que no implicará (potencialmente) tocar el constructor de la entidad.
El enfoque más difícil, pero posiblemente mejor, es pasar sus dependencias a donde las necesita . Sí, esto podría implicar pasar Window *
a un grupo de objetos (como su entidad) de una manera que parezca asquerosa. El hecho de que parezca asqueroso debería decirle algo: su diseño puede ser asqueroso.
La razón por la que esto es más difícil (más allá de involucrar más tipeo) es que esto a menudo conduce a la refactorización de sus interfaces para que lo que "necesita" pasar sea necesario por menos clases de nivel de hoja. Esto hace que gran parte de la fealdad inherente al pasar su renderizador a todo desaparezca, y también mejora la capacidad de mantenimiento general de su código al reducir la cantidad de dependencias y el acoplamiento, la medida en que lo hizo muy obvio al tomar las dependencias como parámetros . Cuando las dependencias eran simples o globales, era menos obvio cuán interconectados estaban sus sistemas.
Pero es potencialmente un importante empresa . Hacerlo en un sistema después del hecho puede ser francamente doloroso. Puede ser mucho más pragmático para ti simplemente dejar tu sistema solo, con el singleton, por ahora (especialmente si estás intentando enviar un juego que de lo contrario funciona bien; a los jugadores generalmente no les importará si tienes un singleton o cuatro allí).
Si desea intentar hacer esto con su diseño existente, es posible que deba publicar muchos más detalles sobre su implementación actual, ya que en realidad no hay una lista de verificación general para realizar estos cambios. O ven a discutirlo en el chat .
Por lo que ha publicado, creo que un gran paso en la dirección "no singleton" sería evitar la necesidad de que sus entidades tengan acceso a la ventana o vista. Sugiere que se dibujan a sí mismos, y no es necesario que las entidades se dibujen a sí mismas . Puede adoptar una metodología donde las entidades solo contienen la información que permitiría mismas para que sean dibujadas por algún sistema externo (que tiene las referencias de ventana y vista). La entidad simplemente expone su posición y el sprite que debe usar (o algún tipo de referencia a dicho sprite, si desea almacenar en caché los sprites reales en el renderizador para evitar tener instancias duplicadas). Simplemente se le dice al renderizador que dibuje una lista particular de entidades, a través de las cuales recorre, lee los datos y usa su objeto de ventana interno para llamar draw
con el sprite buscado para la entidad.