Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2012.01.08;
Скачать: [xml.tar.bz2];

Вниз

Реализация null-методов класса в Delphi   Найти похожие ветки 

 
packpaul ©   (2010-07-14 13:01) [0]

http://chess4net.ru/Upload/NullMethodsInDelphi.zip

В статье описывается паттерн реализации null-методов в Delphi.


 
Двенадцать ©   (2010-07-14 14:26) [1]

Вы пишите
function TTwo.GetInternalValue: Integer;
begin
 Result := FValue;
end;
function TTwo.GetValue: Integer;
begin
 if (Assigned(self)) then
   Result := GetInternalValue
 else
   Result := 0;
end;
получим 0 и будем в твердом убеждении, что объект существует..
а должны бы - ошибку, что б ее обработать.

проблема не нова и есть др.решения, более удобные
ApplicationEvents, например, первое что приходит в голову
а есть и JEDI, с перехватом ошибок, и, опционально, выдачи того места в исходном коде, где она произошла. см. в google "Rouse except intercept"


 
Двенадцать ©   (2010-07-14 14:47) [2]

> Rouse except intercept

всмысле, тут
http://rouse.drkb.ru/


 
packpaul ©   (2010-07-15 16:09) [3]

Это всего лишь паттерн, а то как вы его используете - это на вашей совести.
Есть паттерн null-object, который используется для аналогичных целей, но реализация рефакторинг к этому паттерну более сложный и трудоёмкий.


 
Юрий Зотов ©   (2010-07-15 17:48) [4]

Это паттерн, который МАСКИРУЕТ ошибки в программе, вместо того, чтобы ВЫЯВЛЯТЬ их. Более вредный подход трудно придумать.

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


 
packpaul ©   (2010-07-15 19:09) [5]

Может быть Юрий вы и правы по-своему. Я же думаю, что ошибки должны выявляться в QA, а у заказчика никаких AV не должно лезть - максимум это лог.
Вышеизложенным паттерном можно злоупотребить, как и со всеми паттернами из GOF, впрочем.
Вы, можете вести логгирование в null-method(е), но AV на стороне заказчика - это срам!


 
Юрий Зотов ©   (2010-07-15 20:15) [6]


> packpaul ©   (15.07.10 19:09) [5]

Последний абзац [4] относится и к Вам тоже. После пары недель поиска неизвестно какой и неизвестно где возникающей ошибки Вы со мной согласитесь.

AV у заказчика - это действительно очень плохо. Но в миллион раз хуже, когда заказчик в течение 5 лет эксплуатации программы получал от нее неверные результаты, и, не подозревая этого, использовал их в своей работе. А на 6-м году вдруг случайно обнаружил, что ракеты-то, оказывается, не в ту сторону летят! То есть - нормально стартуют, нормально летят - но только не в ту сторону. Причем не всегда.

И вот говорит заказчик программисту - Вася, исправь программу. Вася, естественно, спрашивает - а что за ошибка-то? Да, мол, ракеты не в ту сторону летят. Всегда, или не всегда? - спрашивает Вася. Не всегда - отвечает ему клиент. А когда? - пытается уточнить Вася? А непонятно когда - говорят ему.

И вот сидит бедняга Вася, и не знает, что и где ему искать. Потому что при нажатии на кнопку "Рассчитать траекторию" в программе не был создан нужный объект - но сработал коварный паттерн и вместо AV выдал неверные параметры траектории - вот ракета и полетела не туда, куда нужно.

Теперь рассмотрим другую ситуацию - когда никакие AV никакими паттернами Вася  не маскировал. Тогда при нажатии на кнопку "Рассчитать траекторию", естественно, возникает AV. Заказчик говорит - Вася, исправь программу. Вася спрашивает - а что за ошибка? А вот какая - говорит клиент и отсылает Васе скриншот. А когда она возникает? - уточняет Вася. А при нажатии на кнопку - отвечает клиент.

Дальше понятно? Точка первого брейкпойнта  у Васи есть - это обработчик OnClick кнопки. Суть ошибки Васе тоже понятна - и простой проход дебаггером вылавливает ошибку максимум за полчаса.

================

Исключения придумали не для того, чтобы их тихо гасить. Их придумали для того, чтобы их обрабатывать - но обработка с гашением возможна далеко не всегда. И вот в этих (наиболее, кстати, частых) случаях гасить исключение ни в коем случае не следует. Пусть ошибка проявит сама себя - тогда ее можно будет быстро и надежно исправить.


 
Германн ©   (2010-07-15 20:23) [7]


> а у заказчика никаких AV не должно лезть

Конечно лучше если повезет получить AV в процессе отладки. Это просто счастье великое! А в противном случае никакой лог может и не помочь. Ведь заказчик не видит никаких проблем. Значит и логи ни смотреть, ни отсылать разработчику не будет. Зачем, если всё работает без сучка, без задоринки?


 
Игорь Шевченко ©   (2010-07-15 20:27) [8]


> В статье описывается паттерн реализации null-методов в Delphi.


статья - это текст, а не архив, не так ли ?


 
packpaul   (2010-07-15 23:23) [9]

http://chess4net.ru/Upload/NullMethodsInDelphi.zip - архив со статьёй и исходным кодом.


 
packpaul   (2010-07-15 23:52) [10]

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

Если активно придерживаться закона Деметры, то можно радикально сократить падение программ из-за неиницилизованных объектов.

Паттерн null-method можно рассматривать как рефакторинг по устранению дублирования кода, когда проверка на null выносится в тело метода. Сегодня как раз использовал это на практике. было что-то вроде:

 if (Assigned(FSaverOne)) then
   FSaverOne.Clear;
 if (Assigned(FSaverTwo)) then
   FSaverTwo.Clear;
 ...
 if (Assignd(FSaverTwoHundred)) then
   FSaverTwoHundred.Clear;


 Превратил Clear в null-method, стало

 FSaverOne.Clear;
 FSaverTwo.Clear;
 ...
 FSaverTwoHundred.Clear;


При этом я ясно осозновал, что TSaver.Clear() никаких расчётов траекторий баллистических ракет не делает и в других контекстах тоже не вызывается.

Вероятно Вася использовал паттерн null-method в не совсем верном контексте.

Люди, когда что-то используете, будьте бдительны!!!


 
Игорь Шевченко ©   (2010-07-16 00:04) [11]

packpaul   (15.07.10 23:23) [9]

В статье не совсем Introduce Null Object, у Фаулера Introduce Null Object довольно неплохо описан, и главное, приведены примеры, когда стоит использовать такую методику.

Проверять внутри объекта, назначен ли Self - это трата времени и сил. Чаще всего, пустая, потому что AV расскажет в этом случае гораздо больше.

Существует два неплохих правила:

1. Не следует маскировать неустойчивость при ошибках программиста, а следует обеспечивать устойчивость при ошибках в данных.
2. Если программа завершается аварийно, это должно происходить явно и по возможности быстро.

Паттерн Null Object разумно использовать в соответствии с этими правилами.


 
Юрий Зотов ©   (2010-07-16 02:50) [12]

> packpaul   (15.07.10 23:52) [10]

> Есть программы, которые маскируют любую ошибку, т.е. пишут ошибки в
> лог.

Это разумная политика для серверных программ. Там ведь юзера нет, на экран глядеть некому, да и самого экрана может не быть. Но если есть экран и юзер, то лучше сделать так, чтобы ошибки замечались сразу же - то есть, выдавать их на экран. Иначе ошибка может долгое время оставаться незамеченной, пусть даже она и пишется в лог.

> Если у заказчика есть нарекания, то его просят прислать лог.

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



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2012.01.08;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.004 c
2-1317392685
Сергей
2011-09-30 18:24
2012.01.08
Как выполнить репликацию Access c помощью Delphi?


2-1317383452
gunny
2011-09-30 15:50
2012.01.08
Delhi Dicom


2-1317379208
suize
2011-09-30 14:40
2012.01.08
шрифты в delphiXe2


15-1316464181
Юрий
2011-09-20 00:29
2012.01.08
С днем рождения ! 20 сентября 2011 вторник


15-1316774640
К-111
2011-09-23 14:44
2012.01.08
Что нужно знать, чтобы выполнить ТЗ?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский