#oop #design-patterns #architecture #game-engine
#ооп #шаблоны проектирования #архитектура #игровой движок
Вопрос:
В настоящее время у нас есть проблема, заключающаяся в том, что наш основной класс GameController
загружается во все внутренние файлы нашей игры. Нам интересно, каковы общие решения этой проблемы.
Вот еще немного об архитектуре игры. Игра представляет собой настольную игру, поэтому, поскольку ~ 90-95% времени ничего не происходит, игра настроена скорее как rest API. Он ожидает запроса пользователя, при получении сообщение распределяется по соответствующим компонентам игры и выполняется надлежащая логика. Нет больших циклов обновления, просто выполняет логику при запросе.
Проблема в том, что, поскольку это сообщение передается каскадом через систему, GameController
оно действует скорее как точка ретрансляции между системами. Это то, как узлы взаимодействуют друг с другом, чтобы все игровые компоненты обновлялись должным образом. Проблема в том, что он создал эту систему, в которой все новые / старые классы содержат указатель на parentGame
, so GameController
везде.
Существуют ли какие-либо простые архитектурные решения, позволяющие избежать того, чтобы каждый класс содержал указатель на parentGame
? Это обязательно плохо?
Некоторый пример кода:
class GameController {
bank: Bank
action: Action
...
}
class Bank {
parentGame: GameController
constructor(game: GameController) {
this.parentGame = game
}
}
class Action {
parentGame: GameController
constructor(game: GameController) {
this.parentGame = game
}
}
Ответ №1:
Я не считаю, что это обязательно плохо, но вы могли бы немного почистить его, обернув его в какой-то механизм события в середине — другими словами, pub / sub может дать вам некоторую развязку, которую вы хотите.
Это не обязательно должно быть что-то, что обменивается данными через внешнюю службу обмена сообщениями — это просто приводит к ненужным накладным расходам. Мне на ум приходит шаблон наблюдателя.
Комментарии:
1. Это хороший ответ. Может ничего не стоить, что статический pub / sub также может помочь в управлении зависимостями здесь. Этот pub / sub всегда может использовать контейнер под капотом, чтобы разрешить замену реализации, но встроенные в память pub / subs в любом случае не препятствуют тестируемости.
GameEvents.publish/subscribe
.