Тут можно МНОГО чего сказать.
Во-первых упомянуть "защитное" и "наступательное" программирование.
"Наступательное" это когда мы ТЕСТИРУЕМ. Тут ВАЖНО, чтобы МАКСИМУМ ошибок "всплывал".
"Защитное" это когда мы отдаём приложение ПОЛЬЗОВАТЕЛЮ, тут важно "ошибки маскировать" и пытаться "восстанавливаться после сбоев".
Это НАДО понимать.
Вообще это СЛОЖНАЯ и ОБШИРНАЯ тема.
Я потом к ней вернусь.
Пока лишь хочу УКАЗАТЬ на ОДНУ РАСПРОСТРАНЁННУЮ ошибку с использованием Assert.
Что-то вроде:
Побоюсь показаться БАНАЛЬНЫМ, но я много видел в коде примерно следующее:
Понятно, что ПРАВИЛЬНО было написать так:
Вообще говоря это РАСПРОСТРАНЁННАЯ ошибка "начинающих", но я её в жизни - МНОГО где видел.
В ПЕРВУЮ очередь надо избегать ПОДОБНЫХ Assert. которые смешивают ИНВАРИАНТЫ и логику.
Кстати вот ссылка про использование Assert - http://18delphi.blogspot.ru/2013/04/blog-post.html
Во-первых упомянуть "защитное" и "наступательное" программирование.
"Наступательное" это когда мы ТЕСТИРУЕМ. Тут ВАЖНО, чтобы МАКСИМУМ ошибок "всплывал".
"Защитное" это когда мы отдаём приложение ПОЛЬЗОВАТЕЛЮ, тут важно "ошибки маскировать" и пытаться "восстанавливаться после сбоев".
Это НАДО понимать.
Вообще это СЛОЖНАЯ и ОБШИРНАЯ тема.
Я потом к ней вернусь.
Пока лишь хочу УКАЗАТЬ на ОДНУ РАСПРОСТРАНЁННУЮ ошибку с использованием Assert.
Что-то вроде:
Побоюсь показаться БАНАЛЬНЫМ, но я много видел в коде примерно следующее:
Assert(Supports(SomeClass, SomeInterface, Instance)); Instance.DoSomeMethod;
Понятно, что ПРАВИЛЬНО было написать так:
if Supports(SomeClass, SomeInterface, Instance)) then Instance.DoSomeMethod else Assert(false);
Вообще говоря это РАСПРОСТРАНЁННАЯ ошибка "начинающих", но я её в жизни - МНОГО где видел.
В ПЕРВУЮ очередь надо избегать ПОДОБНЫХ Assert. которые смешивают ИНВАРИАНТЫ и логику.
Кстати вот ссылка про использование Assert - http://18delphi.blogspot.ru/2013/04/blog-post.html
«Побоюсь показаться БАНАЛЬНЫМ, но я много видел в коде примерно следующее:
ОтветитьУдалитьAssert(Supports(SomeClass, SomeInterface, Instance));
Instance.DoSomeMethod;
Понятно, что ПРАВИЛЬНО было написать так:
if Supports(SomeClass, SomeInterface, Instance)) then
Instance.DoSomeMethod
else
Assert( false );»
-- Не понятно - поясните.
Первый вариант нахожу всем лучше второго, за исключением особенности Assert, состоящей в том, что при сборке версии для пользователя (без отладки) Assert-ы удаляются компилятором.
Ввиду этой особенности, Assert не используется вообще, вместо него применяется своя процедура Contract:
«resourcestring
SEContractViolation = 'Произошла внутренняя ошибка программы. Обратитесь к разработчику.';
SEViolationDetails = 'Служебная информация: модуль %s, строка %d';
procedure Contract(ACondition: Boolean; const AMessage: String = '');
var
ExceptAddr: Pointer;
location: TLocation;
message: String;
begin
if ACondition then Exit;
// получаем адрес места, откуда вызвали Contract
asm
mov EAX, [EBP+$04]
mov ExceptAddr, EAX
end;
if Assigned(GetLocationProc) then
location := GetLocationProc(ExceptAddr);
if AMessage = '' then
message := SEContractViolation
else
message := AMessage;
raise ESContract.CreateFmt(message + ^M^J + SEViolationDetails, [location.SourceName, location.LineNumber]) at ExceptAddr
end;»
которая и применяется в версии для пользователя.