Как обработать недопустимое состояние выполнения? - PullRequest
0 голосов
/ 15 апреля 2009

Скажем, у вас есть следующий блок кода:

if (Light.On) {
    // do something...
} else if (Light.Off) {
    // do something else...
} else {
    // this state should never be reached
}

Теперь предположим, что логика приложения диктует, что в этой части кода никогда не будет достигнуто последнее состояние, но это не то, что может быть определено во время компиляции. И, возможно, существуют другие состояния (например, Light.Broken), которые могут быть установлены другими частями приложения, но которые здесь не используются.

Какой код вы добавляете в последний else блок?

  1. Не добавлять код, потому что он все равно не должен быть достигнут.
  2. Добавьте некоторые функции ведения журнала, чтобы вы, как разработчик, знали, что достигнуто какое-то недопустимое состояние.
  3. Создайте исключение, потому что состояние не должно быть достигнуто, и если оно все равно достигнуто, что-то еще должно быть не так.

Первый вариант мне не кажется разумным, в надежде, что что-то пойдет не так, кажется едва ли правильным выбором. Преимущество второго варианта заключается в том, что ваше приложение не падает сразу, поэтому, если это происходит в редких случаях, которые не были обнаружены в ходе тестирования, заказчик может продолжать использовать приложение, и разработчик получает уведомление о проблеме. Вариант 3 приводит к сбою приложения, что, очевидно, не то, что вы хотите, чтобы ваши клиенты испытывали, но оно дает понять, что что-то не так.

Как лучше всего справиться с такой ситуацией?

РЕДАКТИРОВАТЬ, основываясь на комментариях:

Некоторые дополнительные соображения, чтобы направить обсуждение:

  • Контракт метода, который содержит вышеуказанный код, не позволяет устанавливать какие-либо другие значения в этот момент, кроме On и Off.
  • Предположим, что код находится в не столь критичной части приложения.

Ответы [ 7 ]

6 голосов
/ 15 апреля 2009

В разработке - терпите неудачу и терпите неудачу быстро. Бросить какое-то исключение во время выполнения или просто Assert (false).

В релизе - отключение изящно. Ваше приложение находится в непригодном для использования состоянии, и вы не можете реально использовать все, что обычно делаете, например, инварианты классов и т. Д. Дайте пользователю возможность сохранить свою работу, например, попытаться зарегистрировать ошибку, которая может быть отправлена ​​обратно в Команда разработчиков и затем выключение.

РЕДАКТИРОВАТЬ: На основе добавленных комментариев.

Если в контракте функции указано, что свет должен быть включен или выключен при входе в функцию, то любое другое состояние является ошибкой. Функция должна выйти из строя в соответствии с принципами, изложенными в моем первоначальном ответе.

Относительно «некритического» аспекта - если предварительное условие функции не выполняется, это означает, что ваше приложение не работает. Независимо от того, обнаружена ли ошибка в некритическом фрагменте кода, это не означает, что сама проблема некритична - у вас нет возможности узнать, что ошибка, которая создает недопустимое состояние, также не влияет на критические области кода. .

2 голосов
/ 15 апреля 2009

Ну ... это зависит. Наличие третьего случая для логического теста заставило бы меня плакать. Это просто шум, добавивший путаницу и говорящий, что разработчик, по крайней мере, настолько смущен, насколько это заставляет меня чувствовать.

Для небулева, я думаю, вы могли бы делать что угодно ... Если if захватывает состояния, которые имеют отношение к рассматриваемому коду, нет никакого вреда, просто игнорируя другие случаи. Если есть большая вероятность того, что в будущем потребуются дополнительные случаи, может быть достаточно комментария, чтобы указать это для ясности.

1 голос
/ 15 апреля 2009

Как уже говорилось, на этапе разработки вы должны сделать его видимым как можно скорее. На этапе выпуска это зависит от того, насколько важно достичь этого недопустимого состояния.

Минимум - выпустить журнал для отладки.

Затем вы можете попытаться выйти из этого недопустимого состояния, вернувшись в предыдущее допустимое состояние или перейдя в новое допустимое состояние.

Наконец, если ничего нельзя сделать безопасно, вы можете прекратить выполнение (с предупреждением для пользователя и журналом для сопровождающего).

0 голосов
/ 15 апреля 2009

В разрабатываемой версии просто сгенерируйте исключение.

В версии выпуска:

  • Брось исключение
  • Сохраните работу пользователя во временный файл, если это возможно
  • Сохраните аварийный дамп и (с помощью небольшого вспомогательного приложения) предложите пользователю отправить его вам, чтобы вы могли определить и устранить проблему
0 голосов
/ 15 апреля 2009

Брось исключение.

Как вы сказали, третий случай никогда не должен произойти. Если это произойдет, значит, что-то пошло не так, и вы не знаете, что еще может пойти не так.

Вы также не хотите, чтобы вызывающий код думал, что код работает нормально, даже если он действительно не работает.

Кроме того, намного проще обнаружить проблему до ее выпуска.

0 голосов
/ 15 апреля 2009

Ничего не делай. Если все, что вас волнует, это то, включен ли свет:

if (Light.On) {
    // do some work
} else {
    // too darned dark to work
}

В противном случае вам следует перечислить все ваши состояния.

Если другие состояния не разрешены, вы должны сделать ошибку. Если они разрешены, но не имеют значения, просто игнорируйте их. С правильно разработанным кодом проблем нет.

Ваша главная проблема здесь заключается в дизайне, в котором одновременно могут быть установлены Light.On и Light.Off. Вы должны использовать состояние Light.State, которое имеет одно из следующих значений: {включено, мигает, выключено, сломано, отключено, взорвано, emitting_dangerous_gamma_rays} и т.

0 голосов
/ 15 апреля 2009

3-й вариант является правильным, как будто для этой части любое другое состояние недопустимо, поэтому оно должно выдать исключение, сообщающее о недопустимом состоянии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...