Исключения в сравнении с кодами результатов для клиентского класса сокета
-
02-07-2019 - |
Вопрос
У меня есть класс, который инкапсулирует связь tcp-сокета с сервером.Для каждого командного сообщения, отправленного на сервер, сервер отправит ответное сообщение, которое неизменно содержит код ответа (OK, Сбой).Используя мой класс, каждая команда может выполняться как синхронно, так и асинхронно.
В основном существует два типа исключений, которые могут иметь место:"Ошибка", вызванная отключением или какой-либо другой неустранимой ошибкой и неожиданным исключением типа "буфер отправки заполнен".В случае сбоя никакая команда не может быть продолжена, или повторная попытка, или что-либо еще до тех пор, пока соединение не будет восстановлено.В случае сбоя в ответе или даже исключения команду можно повторить...
Итак, прямо сейчас мои методы команды синхронизации возвращают перечисление, которое может иметь следующие значения:ОК, Сбой, Неисправность.Если возникает исключение, оно просто передается вызывающему потоку (в команде синхронизации).Для асинхронных команд значение enum свойства Result может содержать дополнительное значение:OK, Fail, Ошибка или Исключение, и обратный вызов может получить доступ к фактическому объекту exception через свойство Exception объекта command.
Что вы думаете об этой стратегии?У меня возникает соблазн вообще не создавать исключения для команд синхронизации, а просто зарегистрировать исключение внутренне и вместо этого вернуть 4-е значение enum, потому что это все, что я действительно буду делать с исключениями в любом данном случае...Или я вообще не должен использовать коды результатов и просто создавать исключения во всех случаях, даже при ошибках?
Спасибо.
Решение
Я думаю, что ваша стратегия в принципе разумна.
Имейте в виду, что цель Исключений - иметь дело с исключительными условиями.Чем ближе к источнику проблемы, тем лучше.
В вашем случае, похоже, ваша стратегия выглядит примерно так: "Это не сработало прямо сейчас.Давайте повторим попытку".Я не вижу причин действительно создавать исключения.
Если бы работа с закрытым сокетом требовала совершенно другого потока в вашем коде, тогда, возможно, исключения имели бы смысл.Судя по вашему описанию, на самом деле это не так.
Моя философия относительно исключений заключается в том, что они должны быть для исключительных условий, с которыми вы на самом деле не можете справиться.Закрытая розетка?Хм ... Сколько раз у меня дома отключался интернет...
Другие советы
Я предпочитаю, чтобы вы создавали исключение каждый раз, когда ваш метод успешно не выполняет свою миссию.Поэтому, если я, вызывающий, вызову yourObject.uploadFile() , я буду считать, что файл был успешно загружен, когда вызов вернется.Если это не удастся по какой-либо причине, я ожидаю, что ваш объект выдаст исключение.Если вы хотите провести различие между командами, которые я могу повторить, и командами, которые я не должен повторять, поместите эту информацию в исключение, и я смогу решить, как реагировать соответствующим образом.
При вызове yourObject.BeginAsyncUploadFile() я ожидал бы такого же поведения, за исключением того, что мне нужно было бы дождаться IAsyncResult или эквивалентного объекта, чтобы узнать, удалась загрузка файла или нет, а затем проверить свойство Exception / Error, если это не так.
Как коды результатов, так и исключения могут работать нормально.Это вопрос личного вкуса (и вкуса других членов вашей команды).Исключения имеют некоторые преимущества, особенно в более сложных настройках, но в ваших настройках это звучит достаточно просто, чтобы коды возврата работали нормально.
Некоторые люди будут с пеной у рта настаивать на исключениях, но в моем проекте людям нравится простота кодов возврата, что делает их лучшим выбором в целом.
Это довольно интересный вопрос.Таким образом, вероятно, нет "100% правильного" ответа, и в основном это зависит от того, как, по вашему мнению, должен быть структурирован код, использующий вашу функцию.
Насколько я понимаю, вы используете исключения только тогда, когда хотите предоставить коду, вызывающему вашу функцию, способ изящно выйти из "катастрофической" ситуации.Итак, в моем коде я обычно создаю исключение, когда что-то действительно, в самом деле случается что-то ужасное, и абонент должен знать об этом.
Теперь, если то, что у вас есть, является нормальной и ожидаемой ситуацией, вам, вероятно, следует вернуть значение ошибки.Таким образом, код знает, что ему нужно "стараться сильнее", но то, что произошло, не поставит его под угрозу.
В вашем случае, например, вы могли бы рассматривать тайм-ауты как нечто ожидаемое и, следовательно, возвращать код ошибки и более серьезные проблемы (например, полный буфер отправки), когда вызывающему коду необходимо выполнить некоторые дополнительные действия, чтобы вернуться к "нормальному" состоянию в качестве исключения.
Но с другой стороны, красота в глазах наблюдателя, и некоторые люди скажут вам использовать только исключения, другие (в основном программисты на C) - использовать только коды возврата.Просто помните, что исключения должны всегда будьте исключительными.:)