Проверка данных на нижнем уровне или на верхнем?
От: rmurmur  
Дата: 11.02.06 16:31
Оценка:
Иногда, когда вопрос времени критичен, встает вопрос — где проверять корректность введенных данных — на "нижнем уровне", под которым я здесь понимаю проверку на уровне самых нижних базовых функций, в теле этих функций, или же на "верхнем уровне", под которым я здесь понимаю уровень программы, которая их использует.
Например, если у нас есть условная операция КореньКвадратный (или просто Корень), то логично, что передавать ему в качестве аргумента отрицательное число нельзя, ибо это приведет к сбою на каком-то уровне вычислений. И как раз тут то и встает вопрос — где делать проверку?
В данном примере проверкой на нижнем уровне было бы:
(Приведу что-то похожее на Си для простоты, имена всех функций вымышлены, любые совпадения случайны)

double Root(double argument)
{
if(argument>0)
{
return CalculateRoot(argument)...
}
}

void main()
{
double a = enterA();
output(Root(a));
}

А теперь проверка на верхнем уровне, при этом на нижнем я ее не делаю:

double Root(double argument)
{
return CalculateRoot(argument)...
}

void main()
{
double a = enterA();
if(a>0)
{
output(Root(a));
}
}

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

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

...
A = EnterPOSITIVEvalue;
B = Root(A);
...

Здесь, первая функция сама УЖЕ содержит проверку на положительность, и внутренняя проверка на положительность в Root-е это явная лишняя затрата усилий бедного процессора.

Рассуждая таким образом, я почти всегда делаю лишь внешние проверки, такого вида:

A = EnterValue();
if(IsCorrect(A))
{
func1(A);
func2(A);
func3(A);
...
}

, где func1,func2,func3 крашат всю систему, если данные неверны, но как здесь видно, проверка уже сделана на внешнем уровне.

В принципе, сомнений у меня бы и не возникало, если бы я не встречал функций, которые работают с безопасными системами (я имею ввиду, что если подать неверный параметр, виндоуз не слетит , а процессор не взорвется, максимум — падение программы и небольшая утечка памяти), и при этом в себе содержат много внутренних проверок, при прохождении которых получается либо успешное выполнение, либо вывод ошибки, исключения или еще чего-то, а в программе, где эти функции используются, делаются еще одни проверки, чтобы уже на уровне пользователя вывести ошибку и сообщить пользователю, чтобы он совершил повторный ввод, либо сообщить, что все в порядке... Бывает таким образом чуть-ли не до трех проверок одного и того-же без изменения оного в промежутках между проверками. Зачем?

ЗЫ Я заранее хочу оговорить, что не веду речь о системах, где ошибка в неверном параметре стоит взрыва полконтинента, там естественно внутренняя проверка делается "на всякий случай".
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.