Я проектирую простой контроллер мотора, который может находиться в (по крайней мере) 4 состояниях — холостой ход — ускорение — максимальная скорость — замедление.
Я подумал, что попытка реализовать какой-то конечный автомат будет лучшим способом. В настоящее время использование оператора switch кажется хорошим решением, поскольку оно очень просто и позволяет мне хранить все «движущиеся объекты» в одном объекте (назовем его Move).
Это кажется разумным? Кто-нибудь может предложить более подходящий метод?
Я понимаю, что некоторые предпочитают разбивать каждое состояние на его объект, однако несколько человек сказали мне избегать наследования при записи для MCU.
Я бы не стал использовать здесь наследование не потому, что MCU, а потому что наследование подразумевает абстракцию, а абстракция для 4 состояний не стоит (конечно, есть исключения).
Вы должны решить, хотите ли вы разделить контексты состояний. Если нет, то держите его в одном классе. Если у вас много методов и атрибутов, вы должны разделить их.
Если вам нужно разделить, используйте шаблон состояний или, если у вас мало состояний, сделайте это просто:
Определите класс для каждого государства. Этот класс представляет поведение государства. Не забудьте использовать конструктор в качестве точки входа и деструктор в качестве точки выхода.
Затем определите класс FSM для переключения между состояниями. FSM должен содержать цикл, который создает текущее состояние, запускает его, проверяет его состояние и, при необходимости, уничтожает текущее состояние и создает следующее.
Пример:
// Idle
class Idle {
public:
Idle() {
// entry point
}
~Idle() {
// leaving point
}
void step() {
// actual work
}
// some getters to examine state
private:
// helper methods
// state attributes (context)
};
class FSM {
public:
void run() {
State current(sIdle);
while (current != sExit) {
switch (current) {
case sIdle: {
Idle ctx;
ctx.step();
// examine state
// get user input or
// call step() again or
// decide next state:
current = Accelerate;
break;
}
...
}
}
Что мне нравится в этом дизайне, так это простота, отсутствие функторов (в отличие от шаблона State), и это текущее состояние разрушается до создания следующего. Кроме того, в отличие от шаблона State, реализации состояний не знают о других реализациях состояний.
И не кладите туда абстракцию. Или поместите его туда, но сохраните оригинальную версию, а затем сравните.
Других решений пока нет …