Результат шага
CommandStepResult — объект,
который шаг возвращает после обработки Update.
Он описывает, что должно произойти дальше в рамках многошаговой команды.
Важно понимать:
CommandStepResult управляет только переходами между шагами.
Он не может завершить команду напрямую и не выполняет навигацию.
Эта ответственность принадлежит уровню команды.
—
Структура CommandStepResult
public class CommandStepResult
{
public CommandStepAction Action { get; init; }
public int GoToStepNumber { get; init; }
public CommandStepHoldOnReason HoldOnReason { get; init; }
public string? HoldOnMessage { get; init; }
public static CommandStepResult Next => ...
public static CommandStepResult Previous => ...
public static CommandStepResult HoldOn(...) => ...
public static CommandStepResult GoTo(int stepNumber) => ...
}
Основная идея — один объект описывает намерение шага.
—
Возможные действия
CommandStepAction определяет тип перехода:
public enum CommandStepAction
{
MoveNext,
HoldOn,
MovePrevious,
GoTo
}
### MoveNext
Переход к следующему шагу.
Обычно используется, когда ввод валиден и шаг успешно завершён.
—
### MovePrevious
Переход к предыдущему шагу.
Используется реже, например при реализации кнопки “Назад”.
Если текущий шаг — первый, будет выброшено исключение, так как номер шага не может быть отрицательным.
—
### GoTo
Переход к шагу с конкретным номером.
Позволяет реализовать произвольную логику переходов.
Если номер шага превышает количество шагов в команде, команда считается завершённой.
—
### HoldOn
Оставляет выполнение на текущем шаге.
Используется в ситуациях:
инициализация шага;
некорректный ввод пользователя;
ожидание повторного ввода.
HoldOnMessage позволяет отправить пользователю
сообщение с объяснением причины остановки.
—
Фабричные методы
Для удобства используются статические методы:
CommandStepResult.Next
CommandStepResult.Previous
CommandStepResult.GoTo(stepNumber)
CommandStepResult.HoldOn(reason, message)
Это упрощает читаемость кода шага.
—
Граничные случаи
Поведение оркестратора шагов:
Previousна первом шаге → исключение.Nextна последнем шаге → завершение команды.GoTo(N), гдеNбольше количества шагов → завершение команды.
Таким образом, завершить Stateful-команду можно:
вернув
Nextна последнем шаге;вернув
GoToс номером шага вне диапазона.
—
Связь с CommandResult
CommandStepResult не изменяет ChatSession напрямую.
Он преобразуется оркестратором в соответствующий CommandResult:
MoveNext→GoToStatefulResultHoldOn→HoldOnStatefulResultи т.д.
Подробности логики перехода находятся в реализации Stateful-оркестратора.
—
Практическая модель
Шаг отвечает за локальную логику. Команда отвечает за жизненный цикл. Интерпретаторы отвечают за изменение состояния.
Такое разделение делает поведение предсказуемым и упрощает построение сложных диалогов.