У вас должен быть очень четко определенный набор интерфейсов, которым разрешено передавать или получать сообщения - дать им ссылку на EventScheduler должно быть тривиально. Если это не так, или если вам кажется, что это потребует передачи планировщика событий «слишком большому количеству» различных типов, то у вас может возникнуть проблема с большими проектами (неразборчивая зависимость, которую синглеты имеют тенденцию усугублять, а не решать ).
Помните, что хотя техника передачи планировщика нужным интерфейсам является формой « внедрения зависимостей », в этом случае вы не внедряете новую зависимость. Это зависимость, которая у вас уже есть в системе, но теперь вы делаете ее явной (в отличие от неявной зависимости синглтона). Как правило, явные зависимости более предпочтительны, поскольку они более самодокументированы.
Вы также позволяете себе больше гибкости, отделяя потребителей планирования событий друг от друга (поскольку они не обязательно связаны с одним и тем же планировщиком), что может быть полезно для тестирования или моделирования локальных настроек клиент / сервер или ряда других параметров. - вам могут не понадобиться эти другие варианты, но вы не приложили усилий, чтобы искусственно ограничить себя от них, что является плюсом.
РЕДАКТИРОВАТЬ: все, что я имею в виду, когда я говорю о передаче планировщика, это: если у вас есть какой-то игровой компонент, отвечающий за реагирование на столкновение, он, вероятно, создается с помощью какой-то фабрики по реагированию на столкновения, которая является частью вашего физического уровня. Если вы создаете фабрику с помощью экземпляра планировщика, он может затем передать этот экземпляр любым созданным им респондентам, которые затем могут использовать его для создания событий (или, возможно, подписки на другие события).
class CollisionResponderFactory {
public CollisionResponderFactory (EventScheduler scheduler) {
this.scheduler = scheduler;
}
CollisionResponder CreateResponder() {
return new CollisionResponder(scheduler);
}
EventScheduler scheduler;
}
class CollisionResponder {
public CollisionResponder (EventScheduler scheduler) {
this.scheduler = scheduler;
}
public void OnCollision(GameObject a, GameObject b) {
if(a.IsBullet) {
scheduler.RaiseEvent(E_BIG_EXPLOSION);
}
}
EventScheduler scheduler;
}
Это, очевидно, ужасно надуманный и упрощенный пример, поскольку я не знаю, какова ваша игровая объектная модель; однако он иллюстрирует явную зависимость от планировщика событий и показывает некоторый потенциал для дальнейшей инкапсуляции (вам не обязательно передавать респондерам планировщик, если они взаимодействуют с системой реагирования на столкновения более высокого уровня на том же концептуальном уровне, что и Фабрика, которая имела дело с основными моментами создания событий через планировщик, что изолировало бы каждую отдельную реализацию респондента от подробностей реализации системы диспетчеризации событий, таких как конкретное событие, возникающее при столкновении, которое может быть идеальным для вашей системы - - или не).