Извините, извините, как долго этот вопрос. Я пытался сократить его как можно больше, все еще перечисляя все различные вещи, которые я пробовал, и проблемы, с которыми я столкнулся. Я пытался как можно больше сплотить свой реальный вариант использования, все еще отображая свои проблемы. Automatic до Когда событие «Обновление» не удается управлять автомобилем.
// an interface for controlling a toy car
class CarToy {
public:
// control and inspect the toy's output settings
void setSpeed(float speed);
float getSpeed() const;
void setSteering(float steering);
float getSteering() const;
// obtain information about the toy in relation to the world
Direction getFacingDirection() const;
Position getPosition() const;
};
// a controller for the car that can be set to two modes, automatic or manual
// update() is called periodically to keep automatic mode working
class CarToyController {
public:
enum class CarMode { manual, automatic, off };
private:
CarToy _car;
CarMode _mode; // controls whether car goes to destination or is in manual
Position _destination; // target destination for automatic mode
public:
explicit CarToyController(CarToy car) : _car(car) {
_mode = CarMode::off;
_destination = Position(); // whatever the default constructor makes
_car.setSpeed(0.0f);
_car.setSteering(0.0f); // centered
}
const CarToy& getCar() { return _car; }
void setState(CarMode mode) {
_mode = mode;
switch (_mode) {
case CarMode::off:
_car.setSpeed(0.0f);
_car.setSteering(0.0f);
break;
case CarMode::manual:
_car.setSpeed(0.0f);
_car.setSteering(0.0f);
break;
case CarMode::automatic:
autoSteer(); // defined below
break;
}
}
void SetManualSpeed(float speed) {
if (_mode == CarMode::manual) { _car.setSpeed(speed); }
}
void SetManualSteering(float steering) {
if (_mode == CarMode::manual) { _car.setSteering(steering); }
}
void SetAutoDestination(Position destination) {
// note that this destination is saved, regardless of whether the automatic mode is active or not
_destination = destination;
}
void Update() {
if (_mode == CarMode::automatic) {
autoSteer();
}
}
private:
void autoSteer() {
if (crashed(_car)) {
setState(CarMode::off);
} else {
// call some logic which determines how to steer the car to the destination
float newSpeed = determineNewSpeed(_car, _destination); // car is a const reference in these methods
float newSteering = determineNewSteering(_car, _destination);
_car.setSpeed(newSpeed);
_car.setSteering(newSteering);
}
}
};
< /code>
Этот код может быть четко улучшен, отделяя ручную логику от автоматической логики, используя стратегическую шаблон. осуществлять. Этот интерфейс имеет метод для каждого типа события, с которым необходимо обработать состояние. Каждый из этих методов должен пройти по предмету (в данном случае, структура, содержащая автомобиль, и IRL: также некоторые другие объекты, которые управляются). Этот интерфейс не знает ни о каком из других расширенных методов в каждом режиме. < /P>
Я сталкиваюсь с несколькими нежелательными вариантами, поскольку я пытаюсь преследовать твердые принципы, чтобы упростить бегемот состояния машины, который у меня на самом деле имею (с более чем 60 различными расширенными переменными, такими как _destination, в том числе некоторые, которые ведут себя как Hierarchical State Machine Supate Spectrees). /> Реализуйте каждый расширенный метод каждого режима в контроллере, а затем: < /p>
a) ... Проверьте каждый реализованный метод, является ли соответствующий режим или нет, и либо вызовите его поведение по умолчанию, либо привлечено, либо вызовут его активное поведение: < /p>
CarController::setManualSteering(float steering) {
if (_mode == manualMode) { manualMode.SetSteering(_car, steering); }
}
< /code>
Это не полиморфно и по -прежнему требует довольно большого количества такого же багажа, что и у государственной машины. CarController::setManualSteering(float steering) { _mode.setManualSteering(steering); }
OffMode::setManualSteering(float steering) {}
AutomaticMode::setManualSteering(float steering) {}
ManualMode::setManualSteering(float steering) { _subject.car.setSteering(steering) }
< /code>
Это немного лучше, но он не работает для таких вещей, как установка автоматического направления, которое работает одинаково, независимо от того, какое это состояние. ManualMode::onEnter() { _subject.manualDomain.setModeReference(this); }
ManualMode::onExit() { _subject.manualDomain.setModeReference(nullptr); }
ManualDomain::setSteering(float steering) { //
Подробнее здесь: https://stackoverflow.com/questions/795 ... te-pattern
Как я могу превратить машину монолитного состояния в рисунок полиморфного состояния, когда в каждом состоянии есть уника ⇐ C++
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Средние расходы клиентов в каждом месяце и количество заказанных товаров в каждом месяце.
Anonymous » » в форуме JAVA - 0 Ответы
- 36 Просмотры
-
Последнее сообщение Anonymous
-