У меня есть приложение, которое имеет несколько состояний, причем каждое состояние реагирует на ввод по-разному.Лучший способ обработки изменений ввода и состояния для нескольких состояний?
Первоначальная реализация была выполнена с помощью большого оператора 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 в конкретных состояниях? This question предлагает шаблон команды, но я не понимаю, как я буду использовать его здесь. Может кто-нибудь помочь объяснить это или предложить другое решение?
В качестве побочного примечания я рассмотрел (и не против) идею позволить классу App выполнить опрос ОС, а затем передать входы в _current_state-> handleInput. На самом деле, что-то говорит мне, что я хочу сделать это как часть рефакторинга. Я еще не сделал этого.
Во-вторых, изменения состояния производятся путем вызова App :: setCurrentState (newstate). Я понимаю, что это сродни использованию глобалов, но я не уверен в лучшем способе сделать это. Моя главная цель - добавить состояния без изменения класса App. Предложения также приветствуются здесь.
Инкапсулирование ввода в один класс будет достаточно простым. Хотя, Я не понимаю, как будет действовать цепочка ответственности, поскольку одновременно будет действовать только одно состояние. – 2008-12-05 23:34:42