Чья ответственность должна быть для проверки предварительных условий?

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

Соглашение звучит примерно так: «если вызывающая сторона обеспечивает выполнение предварительных условий функции, то функция будет вести себя ожидаемым образом и / или возвращать ожидаемые значения».

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

Что касается наилучшего подхода к архитектуре и дизайну программного обеспечения?

2

Решение

Это ответственность звонящего. Например, что может быть реализация strlen делать, если передан нулевой указатель? Единственное, что он может сделать, — это прервать программу — что является жизнеспособным, хотя и радикальным вариантом в C. В C ++ он может вызвать исключение (но не в том случае, если он соответствует стандарту C ++), но работа с этим исключением будет очень сложно. Таким образом, единственное разумное решение, которое позволяет программе продолжать работать в известном состоянии, это для strlen не вызываться с нулевым указателем в качестве параметра, что возлагает ответственность за проверку этого на вызывающий код.

3

Другие решения

Как говорил Нил, проверка является обязанностью звонящего. Вы сказали,

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

Чтобы описать, почему это не идеальный подход, я остановлюсь на примере Нейла, который использовал проверку на нулевые указатели, передаваемые strlenПредставьте себе два сценария:

  1. Функция, которая называется strlen проверяет ввод заранее.
  2. strlen проверяет свои аргументы внутри, прежде чем оперировать ими.

Нет никакой разницы в эффективности между этими двумя методами, если вы делаете один вызов strlen, Тем не менее, представьте, что вместо одного звонка strlen, ты звонишь strlen, strstrи другие строковые функции несколько раз подряд. В сценарии 1, независимо от того, выполняете ли вы 1, 2, 10 или 100 вызовов функций из строковой библиотеки, вам нужно проверять только неправильные входные данные один раз. В сценарии 2 каждый вызов вынужден проверять ввод, что значительно замедляет процесс.

1

По вопросам рекламы [email protected]