Иногда, когда вопрос времени критичен, встает вопрос — где проверять корректность введенных данных — на "нижнем уровне", под которым я здесь понимаю проверку на уровне самых нижних базовых функций, в теле этих функций, или же на "верхнем уровне", под которым я здесь понимаю уровень программы, которая их использует.
Например, если у нас есть условная операция КореньКвадратный (или просто Корень), то логично, что передавать ему в качестве аргумента отрицательное число нельзя, ибо это приведет к сбою на каком-то уровне вычислений. И как раз тут то и встает вопрос — где делать проверку?
В данном примере проверкой на нижнем уровне было бы:
(Приведу что-то похожее на Си для простоты, имена всех функций вымышлены, любые совпадения случайны)
Встает вопрос, где ее делать в каких случаях? Естественно, делать и там и там неразумно, ибо получится, что два раза проверяем одно и тоже (за исключением хитрых случаев ветвления, но мы берем простейший случай).
С одной стороны, довольно опасно оставлять функции без всяких внутренних проверок, ибо случайно можно передать не тот параметр, забыв внешне проверить правильность данных, но, с другой стороны, неразумно тратить ресурсы на вызов проверок тогда, когда данные, поступающие заранее правильны. Пример:
...
A = EnterPOSITIVEvalue;
B = Root(A);
...
Здесь, первая функция сама УЖЕ содержит проверку на положительность, и внутренняя проверка на положительность в Root-е это явная лишняя затрата усилий бедного процессора.
Рассуждая таким образом, я почти всегда делаю лишь внешние проверки, такого вида:
A = EnterValue();
if(IsCorrect(A))
{
func1(A);
func2(A);
func3(A);
...
}
, где func1,func2,func3 крашат всю систему, если данные неверны, но как здесь видно, проверка уже сделана на внешнем уровне.
В принципе, сомнений у меня бы и не возникало, если бы я не встречал функций, которые работают с безопасными системами (я имею ввиду, что если подать неверный параметр, виндоуз не слетит , а процессор не взорвется, максимум — падение программы и небольшая утечка памяти), и при этом в себе содержат много внутренних проверок, при прохождении которых получается либо успешное выполнение, либо вывод ошибки, исключения или еще чего-то, а в программе, где эти функции используются, делаются еще одни проверки, чтобы уже на уровне пользователя вывести ошибку и сообщить пользователю, чтобы он совершил повторный ввод, либо сообщить, что все в порядке... Бывает таким образом чуть-ли не до трех проверок одного и того-же без изменения оного в промежутках между проверками. Зачем?
ЗЫ Я заранее хочу оговорить, что не веду речь о системах, где ошибка в неверном параметре стоит взрыва полконтинента, там естественно внутренняя проверка делается "на всякий случай".
Re: Проверка данных на нижнем уровне или на верхнем?
Здравствуйте, Kubyshev Andrey, Вы писали:
KA>Я тоже об этом подумывал и пришел к выводу. Сделать можно по всякому, только поведение какое бы оно ни было надо задокументировать.
Несомненно, документация обязательна. В принципе я тоже пришел к выводу, что делать стоит "как удобно", если из ситуации это не очевидно... А именно, я почти всегда делаю внешние проверки исключительно =)
Re: Проверка данных на нижнем уровне или на верхнем?
Hello, "rmurmur" > > С одной стороны, довольно опасно оставлять функции без всяких внутренних проверок, ибо случайно можно передать не тот параметр, забыв внешне проверить правильность данных, но, с другой стороны, неразумно тратить ресурсы на вызов проверок тогда, когда данные, поступающие заранее правильны.
Лучше вообще никого без проверок не оставлять. При этом, для внешнего интерфейса, проверка может быть в виже возврата ошибки/выброса исключения. А для внутреннего интерфейса проверка может быть в виде ASSERTа который будет автоматически удален в Release конфигурации.
Posted via RSDN NNTP Server 2.0
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[2]: Проверка данных на нижнем уровне или на верхнем?
Kubyshev Andrey wrote:
> Я тоже об этом подумывал и пришел к выводу. Сделать можно по всякому, > только поведение какое бы оно ни было надо задокументировать.
Правильно, а в случае С,С++ всё обильно посыпать assert-ами.
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[3]: Проверка данных на нижнем уровне или на верхнем?
kan_izh wrote: >> Я тоже об этом подумывал и пришел к выводу. Сделать можно по всякому, >> только поведение какое бы оно ни было надо задокументировать. > Правильно, а в случае С,С++ всё обильно посыпать assert-ами.
Assert'ы — это не средство проверки ошибок (как у некоторых ), а
метод контроля целостности программы.
Posted via RSDN NNTP Server 2.0
Sapienti sat!
Re[4]: Проверка данных на нижнем уровне или на верхнем?
Cyberax wrote: >> > Я тоже об этом подумывал и пришел к выводу. Сделать можно по всякому, >> > только поведение какое бы оно ни было надо задокументировать. >> Правильно, а в случае С,С++ всё обильно посыпать assert-ами. > Assert'ы — это не средство проверки ошибок (как у некоторых ), а > метод контроля целостности программы.
Что ты здесь подразумеваешь под целостностью и под ошибкой?
Если у меня выскакивает ассерт, это означает, что программа работает неправильно (работает! ассерт не фатален. но
неправильно... ), требуется исправить ошибки в программе.
Т.е. я бы обязательно написал так:
Здравствуйте, TK, Вы писали:
TK>Hello, "rmurmur" >> >> С одной стороны, довольно опасно оставлять функции без всяких внутренних проверок, ибо случайно можно передать не тот параметр, забыв внешне проверить правильность данных, но, с другой стороны, неразумно тратить ресурсы на вызов проверок тогда, когда данные, поступающие заранее правильны.
TK>Лучше вообще никого без проверок не оставлять. При этом, для внешнего интерфейса, проверка может быть в виже возврата ошибки/выброса исключения. А для внутреннего интерфейса проверка может быть в виде ASSERTа который будет автоматически удален в Release конфигурации.
С этим я пожалуй соглашусь. Я скорее имел ввиду проверки, которые останутся в релизе
Re[3]: Проверка данных на нижнем уровне или на верхнем?
Здравствуйте, rmurmur, Вы писали:
R>Иногда, когда вопрос времени критичен, встает вопрос — где проверять корректность введенных данных — на "нижнем уровне", под которым я здесь понимаю проверку на уровне самых нижних базовых функций, в теле этих функций, или же на "верхнем уровне", под которым я здесь понимаю уровень программы, которая их использует.
С. Макконнелл в "Совершенном коде" писал: "Используйте процедуры обработки ошибок для ожидаемых событий и утверждения для событий, которые происходить не должны".
То есть, если входные данные поступили в функцию из ненадежного источника (пользователя), валидность входных данных следует проверять через выброс исключения или код возврата по направлению к клиенту. Клиент же волен делать с этой информацией что ему угодно: вывести сообщение пользователю, молча завершиться, а то и просто проигнорировать под свою ответственность. То есть коды возврата/исключения служат для контроля ошибок пользователя.
Если же данные поступили из надежного источника, валидность входных данных следует проверять через утверждения (assertions). Надежность источника определяет сам программист, например, программист может сказать, что открытые члены класса являются надежныи источником для закрытых членов. Если же "надежный" источник вдруг осказался ненадежным, сработает утверждения, которое уже не оставит шансов на продолжение работы. То есть assertions служат для контроля ошибок программиста.
-- Андрей
Re: Проверка данных на нижнем уровне или на верхнем?
Здравствуйте, rmurmur, Вы писали:
R>Иногда, когда вопрос времени критичен, встает вопрос — где проверять корректность введенных данных — на "нижнем уровне", под которым я здесь понимаю проверку на уровне самых нижних базовых функций, в теле этих функций, или же на "верхнем уровне", под которым я здесь понимаю уровень программы, которая их использует.
Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.
Хоар
Re[2]: Проверка данных на нижнем уровне или на верхнем?
Здравствуйте, AVC, Вы писали:
AVC>Здравствуйте, rmurmur, Вы писали:
R>>Иногда, когда вопрос времени критичен, встает вопрос — где проверять корректность введенных данных — на "нижнем уровне", под которым я здесь понимаю проверку на уровне самых нижних базовых функций, в теле этих функций, или же на "верхнем уровне", под которым я здесь понимаю уровень программы, которая их использует.
AVC>Этот вопрос в свое время исследовал Бертран Мейер (автор языка Eiffel) и создал понятие "проектирование по контракту": AVC>http://en.wikipedia.org/wiki/Design_by_contract
+1
Может немного в сторону темы, однако добавлю, что его трактовка LSP в терминах пред- и постусловий: “When redefining a routine [in a derivative], you may only replace its precondition by a weaker one, and its postcondition by a stronger one” означает, что требования к входным данным для подтипа должны быть такими же или более лояльными, чем и для базового типа.
-- Андрей
Re[5]: Проверка данных на нижнем уровне или на верхнем?
твое внутренние противоречие: R>Встает вопрос, где ее делать в каких случаях? Естественно, делать и там и там неразумно, ибо получится, что два раза проверяем одно и тоже
и разрешение твоего противоречия: R>...(я имею ввиду, что если подать неверный параметр, виндоуз не слетит , а процессор не взорвется, максимум — падение программы и небольшая утечка памяти), и при этом в себе содержат много внутренних проверок,
т.е. далать и там и там
(большинство проверок отнимают очень мало процессороного времени)
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[6]: Проверка данных на нижнем уровне или на верхнем?
Odi$$ey wrote:
>> Assert'ы — это не средство проверки ошибок (как у некоторых ), а метод > контроля целостности программы. > > +1 > > _>Если у меня выскакивает ассерт, это означает, что программа работает > неправильно > > нет, это значит ее неправильно используют > > _>требуется исправить ошибки в программе. > > assert — это как линейкой по рукам — от того кто писал код тому кто его > использует
Ты путаешь "программа" и "код", или не так понял, что я подразумеваю тут под программой. Программа используется
пользователем, идеальная программа не может быть использвана неправильно (в общем-то поэтому из релизной сборки
убираются asserts).
Posted via RSDN NNTP Server 2.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай