У меня есть приложение с несколькими состояниями, каждое из которых по-разному реагирует на ввод.
Первоначальная реализация была сделана с помощью большого оператора switch, который я реорганизовал с использованием шаблона состояния (по крайней мере, я думаю, что это шаблон состояния. Я немного новичок в использовании шаблонов проектирования, поэтому склонен запутывать ) -
class App {
public:
static App * getInstance();
void addState(int state_id, AppState * state) { _states[state_id] = state; }
void setCurrentState(int state_id) { _current_state = _states[state_id]; }
private:
App()
~App();
std::map<int, AppState *> _states;
AppState * _current_state;
static App * _instance;
}
class AppState {
public:
virtual void handleInput() = 0;
virtual ~AppState();
protected:
AppState();
}
В настоящее время каждое состояние опрашивает ОС на предмет ввода и действует соответственно. Это означает, что каждое конкретное состояние имеет огромный оператор switch с регистром для каждого допустимого нажатия клавиши. В некоторых случаях вызов функций, а в других случаях изменения состояния вызываются с помощью App :: setCurrentState (newstate). Подвох в том, что ключ, который делает что-то в одном состоянии, может ничего не делать (или в редких случаях может делать что-то другое) в другом состоянии.
Хорошо, я думаю, что это уместный фон. Вот актуальный вопрос (ы) -
Во-первых, каков наилучший способ устранить огромные операторы switch в конкретных состояниях? Этот вопрос предлагает образец команды, но я не понимаю, как бы я использовал его здесь. Может кто-нибудь помочь объяснить это или предложить другое решение?
В качестве примечания я рассмотрел (и не против) идею о том, чтобы позволить классу App выполнять опрос операционной системы, а затем передавать входные данные в _current_state-> handleInput. На самом деле, что-то говорит мне, что я хочу сделать это как часть рефакторинга. Я просто еще этого не сделал.
Во-вторых, изменения состояния производятся путем вызова App :: setCurrentState (newstate). Я понимаю, что это похоже на использование глобалов, но я не уверен в лучшем способе сделать это. Моя главная цель - иметь возможность добавлять состояния без изменения класса App. Предложения будут приветствоваться и здесь.