Является ли хорошей практикой реализация бесполезной обработки исключений на случай, если другая часть кода не закодирована правильно?
Основной пример
Простой, так что я не теряю всех :).
Допустим, я пишу приложение, которое будет отображать информацию о человеке (имя, адрес и т. Д.), Данные извлекаются из базы данных. Допустим, я один кодирую часть пользовательского интерфейса, а кто-то другой пишет код запроса БД.
Теперь представьте, что в спецификациях вашего приложения сказано, что если информация о человеке неполная (скажем, имя отсутствует в базе данных), человек, кодирующий запрос, должен обработать это, возвращая «NA» для отсутствующего поля.
Что если запрос плохо закодирован и не обрабатывает этот случай? Что если парень, который написал запрос, обработает вам неполный результат, и когда вы попытаетесь отобразить информацию, все рухнет, потому что ваш код не подготовлен для отображения пустых вещей?
Этот пример очень простой. Я полагаю, что большинство из вас скажут: «Это не ваша проблема, вы не несете ответственности за этот сбой». Но это все еще ваша часть кода, которая терпит крах.
Другой пример
Допустим, сейчас я пишу запрос. В спецификациях говорится не то же самое, что и выше, но тот, кто пишет запрос «вставка», должен убедиться, что все поля заполнены при добавлении человека в базу данных, чтобы избежать вставки неполной информации. Должен ли я защитить свой запрос «select», чтобы убедиться, что я предоставляю пользователю UI полную информацию?
Вопросы
Что если в спецификациях явно не сказано «этот парень отвечает за решение этой ситуации»? Что, если третье лицо реализует другой запрос (аналогично первому, но в другой БД) и использует ваш код пользовательского интерфейса для его отображения, но не обрабатывает этот случай в своем коде?
Должен ли я сделать то, что необходимо для предотвращения возможного сбоя, даже если я не тот, кто должен заниматься плохим случаем?
Я не ищу такой ответ, как «(с) он несет ответственность за аварию», так как я не решаю конфликт здесь, я хотел бы знать, должен ли я защищать свой код от ситуаций, это не моя ответственность обрабатывать? Здесь достаточно простого «если что-то пустое».
В общем, этот вопрос решает избыточную обработку исключений. Я спрашиваю об этом, потому что когда я работаю один над проектом, я могу 2-3 раза кодировать аналогичную обработку исключений в последовательных функциях, «на всякий случай», я сделал что-то не так и позволил выйти из строя плохому делу.
Ответы:
То, о чем вы говорите, это границы доверия . Вы доверяете границе между вашим приложением и базой данных? Доверяет ли база данных, что данные из приложения всегда предварительно проверяются?
Это решение должно приниматься в каждом приложении, и нет правильных и неправильных ответов. Я склонен ошибаться, называя слишком много границ границей доверия, другие разработчики будут с радостью доверять сторонним API-интерфейсам делать то, что вы ожидаете от них, всегда и всегда.
источник
Принцип надежности «Будь консервативен в том, что ты посылаешь, будь либеральным в том, что ты принимаешь» - вот чего ты добиваешься. Это хороший принцип - РЕДАКТИРОВАТЬ: до тех пор, пока его приложение не скрывает серьезных ошибок, - но я согласен с @pdr, что от ситуации всегда зависит, применять ее или нет.
источник
Это зависит от того, что вы тестируете; но давайте предположим, что область вашего теста - только ваш собственный код. В этом случае вы должны проверить:
Чтобы сделать это, вы не можете использовать компонент вашего коллеги: вместо этого используйте mocking , то есть замените остальную часть приложения «поддельными» модулями, которыми вы можете управлять из среды тестирования. Как именно вы это сделаете, зависит от способа взаимодействия модулей; Этого может быть достаточно, чтобы просто вызывать методы вашего модуля с жестко закодированными аргументами, и это может стать таким же сложным, как написание целого фреймворка, связывающего публичные интерфейсы других модулей со средой тестирования.
Это всего лишь пример модульного теста. Вам также нужны интеграционные тесты, в которых вы тестируете все модули совместно. Опять же, вы хотите проверить как счастливый случай, так и неудачи.
В случае «базового примера» для модульного тестирования кода напишите фиктивный класс, имитирующий уровень базы данных. Ваш ложный класс на самом деле не попадает в базу данных: вы просто предварительно загружаете его ожидаемыми входными данными и фиксированными выходными данными. В псевдокоде:
А вот как вы должны проверить пропущенные поля, о которых сообщается правильно :
Теперь все становится интересным. Что если настоящий класс БД ведет себя плохо? Например, это может вызвать исключение по непонятным причинам. Мы не знаем, так ли это, но мы хотим, чтобы наш собственный код обрабатывал это изящно. Нет проблем, нам просто нужно заставить наш MockDB генерировать исключение, например, добавив такой метод:
И тогда наш тестовый пример выглядит так:
Это ваши юнит-тесты. Для интеграционного теста вы не используете класс MockDB; вместо этого вы объединяете оба фактических класса вместе. Вам все еще нужны светильники; например, вы должны инициализировать тестовую базу данных в известное состояние перед запуском теста.
Теперь, что касается ответственности: ваш код должен ожидать, что остальная часть кодовой базы будет реализована в соответствии со спецификацией, но он также должен быть готов к тому, чтобы обрабатывать вещи изящно, когда все остальное искажается. Вы не несете ответственности за тестирование кода, отличного от вашего, но вы несете ответственность за то, чтобы сделать ваш код устойчивым к неправильному поведению кода на другом конце, а также за тестирование устойчивости своего кода. Это то, что делает третий тест выше.
источник
Есть 3 основных принципа, по которым я пытаюсь кодировать:
DRY
ПОЦЕЛУЙ
YAGNI
Проблема заключается в том, что вы рискуете написать проверочный код, который дублируется в другом месте. Если правила проверки изменятся, их необходимо будет обновить в нескольких местах.
Конечно, в какой-то момент в будущем вы можете переплатформировать свою базу данных (это случается), и в этом случае вы можете подумать, что иметь код в нескольких местах было бы выгодно. Но ... ты кодируешь что-то, что может не произойти.
Любой дополнительный код (даже если он никогда не изменяется) является непроизводительным, поскольку его необходимо будет написать, прочитать, сохранить и протестировать.
Если все вышесказанное является правдой, было бы упущением с вашей стороны вообще ничего не делать. Чтобы отобразить полное имя в приложении, вам понадобятся некоторые базовые данные, даже если вы не проверяете сами данные.
источник
По словам непрофессионала.
Нет такой вещи как «база данных» или «приложение» .
Опять таки:
источник