Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.03.02;
Скачать: CL | DM;

Вниз

Delphi типы исключений.   Найти похожие ветки 

 
DVM ©   (2008-01-27 21:00) [80]


> Семеныч

В диалоге кнопки OK и Отмена. Нажатие кнопки Ок проверяет поля и если что не так сообщает пользователю об ошибках и предлагает исправить. Если ошибок нет, то ModalResult:=mrOk;


 
Черный Шаман   (2008-01-27 21:01) [81]


> Игорь Шевченко ©   (27.01.08 20:40) [77]
> > Юзер ввел в Edit заведомо неверные данные и жмякнул ОК.
>
> > Программа обнаружила его ошибку и вместо того, чтобы принять
> > данные и закрыть диалог ввода, выдала ему вразумительное
> > сообщение и попросила либо исправить данные, либо нажать
> > "отмену".
> >
> > Данные программа не исправила, она этого и не могла сделать.
>
> >  А ситуацию - исправила. И совершенно спокойно может продолжать
> > работать.
>
>
> Тут можно долго бодаться с терминологией, я согласен с А.
> П. [54]


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


 
Черный Шаман   (2008-01-27 21:02) [82]


> Семеныч   (27.01.08 20:51) [78]
>
> > Черный Шаман   (27.01.08 20:08) [66]
>
> > при false стереть edit и установить фокус на него.
>
> Какой Edit? Никаких Edit"ов уже нет - диалог-то уже закрылся.
>  Иначе как он мог вернуть код возврата, не закрываясь? Диалоги
> - же они по сути своей должны быть модальными. Или второй
> раз поднимать тот же диалог? А зачем такие сложности городить?
>
>
> Но если использовать не код возврата, а исключение, то диалог
> может и не закрываться
.


if then Exit?


 
Anatoly Podgoretsky ©   (2008-01-27 21:04) [83]

> DVM  (27.01.2008 21:00:20)  [80]

Именно там и желательно подсветить все поля, а не только первое которое неверное, а фокус установить на первое неверно, по TabOrder
Если это не сделать, то пользователь возможно долго будет устранять ошибки.


 
Семеныч   (2008-01-27 21:27) [84]

> Черный Шаман   (27.01.08 21:02) [82]

> if then Exit?

???????????

Пусть мы имеем N разных диалоговых форм ввода. Делам их предка. В нем ставим стиль "диалог", кнопки ОК (с Default=True) и Отмена (с Cancel=True и ModalResult=mrCancel), абстрактный метод validate и обработчик OK.OnClick. В этом обработчике 2 строчки:

Validate;
ModalResult := mrOK;

Все это значит, что диалог закроется только если:
- юзер нажал кнопку Отмена (вызывающий код получит mrCancel);
- юзер ввел верные данные и нажал ОК (вызывающий код получитmrOK) .

От этого предка плодим конкретные формы ввода. Каждая форма знает свои поля и какие данные в них допустимы, а какие заведомо недопустимы. Поэтому каждая конкретная форма может свои данные проверить. Это она делает в методе Validate. Если код этого метода обнаружил ошибку, то он просто поднимает Exception с вразумительным текстом. Например:

procedure TSomeForm.Validate;
begin
 if TargetName = "" then
   raise EInvalidInput.Create("Необходимо указать наименование");
 if StartDate > FinishDate then
   raise EInvalidInput.Create("Дата начала не может быть позже даты окончания");
 ... // и т.п.
end;

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

with TSomeForm.Create(nil) do
try
 if ShowModal = mrOK then
 begin
   ... // Забираем введенные юзером данные
 end;
finally
 Free;
end;

Какие Exit? Все просто, как веник.


 
Семеныч   (2008-01-27 21:31) [85]

> DVM ©   (27.01.08 21:00) [80]

Так и я о том же. И никакие коды возврата не нужны. А сообщение об ошибке удобно выдавать юзеру именно через Exception - тогда код валидации становится максимально простым (см. выше).


 
DVM ©   (2008-01-27 21:37) [86]


> тогда код валидации становится максимально простым (см.
> выше).

Ну простым или нет это спорный вопрос. Короче он точно сильно не становится. А вот читабельнее - это кому как нравится. Кому то удобнее выдавать сообщения об шибке по месту и потом делать Exit, кому то складировать все сообщения об ошибках после except.


 
Черный Шаман   (2008-01-27 21:46) [87]


>
> Пусть мы имеем N разных диалоговых форм ввода. Делам их
> предка. В нем ставим стиль "диалог", кнопки ОК (с Default=True)
> и Отмена (с Cancel=True и ModalResult=mrCancel), абстрактный
> метод validate и обработчик OK.OnClick. В этом обработчике
> 2 строчки:
>
> Validate;
> ModalResult := mrOK;


if Validate then
ModalResult := mrOK;


 
Игорь Шевченко ©   (2008-01-27 21:56) [88]

Семеныч   (27.01.08 21:27) [84]


> Пусть мы имеем N разных диалоговых форм ввода. Делам их
> предка. В нем ставим стиль "диалог", кнопки ОК (с Default=True)
> и Отмена (с Cancel=True и ModalResult=mrCancel), абстрактный
> метод validate и обработчик OK.OnClick. В этом обработчике
> 2 строчки:
>
> Validate;
> ModalResult := mrOK;


При вводе я примерно также делаю, за одним исключением:

if Validate then
 ModalResult := mrOk

Мне необработанные конкретной формой исключения совсем неинтересны.


> Это единственный метод, который должна реализовать каждая
> форма ввода, весь остальной функционал уже зашит в предке.
>  Вызывающий код тоже единообразен и прост до невозможности:
>
>
> with TSomeForm.Create(nil) do
> try
>  if ShowModal = mrOK then
>  begin
>    ... // Забираем введенные юзером данные
>  end;
> finally
>  Free;
> end;


Я бы Free убрал.


 
Семеныч   (2008-01-27 21:58) [89]

> Черный Шаман   (27.01.08 21:46) [87]

Угу. И вот ТОГДА как раз в Validate и придется писать Ваши if - exit:

if Чих1 then
begin
 MessageBox(...);
 Result := False;
 Exit;
end;

Вместо:

if Чих1 then
 raise EInvalidInput.Create(...);

И таких "Чихов" будет не один. Что проще и короче?


 
DVM ©   (2008-01-27 22:01) [90]


> И таких "Чихов" будет не один. Что проще и короче?

Конечно проще и короче второй, но EInvalidInput надо где то определить - это раз, потом это напоминает какую-то современную реинкарнацию goto


 
Семеныч   (2008-01-27 22:01) [91]

> Игорь Шевченко ©   (27.01.08 21:56) [88]

> Я бы Free убрал.

От задачи зависит. Если форма не должна хранить последние введенные в нее данные, то и держать ее незачем.


 
Семеныч   (2008-01-27 22:03) [92]

> DVM ©   (27.01.08 22:01) [90]
> напоминает какую-то современную реинкарнацию goto

А Exit ее не напоминает?
:о)


 
DVM ©   (2008-01-27 22:03) [93]


> А Exit ее не напоминает?

А можно и без него.


 
Игорь Шевченко ©   (2008-01-27 22:04) [94]

Семеныч   (27.01.08 22:01) [91]


> От задачи зависит. Если форма не должна хранить последние
> введенные в нее данные, то и держать ее незачем.


Безусловно


 
DVM ©   (2008-01-27 22:05) [95]


> От задачи зависит. Если форма не должна хранить последние
> введенные в нее данные, то и держать ее незачем.

Более красиво в конструктор передать структуру, которая должна быть заполнена, а Free оставить.


 
Семеныч   (2008-01-27 22:22) [96]

> Игорь Шевченко ©   (27.01.08 21:56) [88]
> Мне необработанные конкретной формой исключения совсем неинтересны.
Они приходят в дефолтный обработчик. Нормально.

> DVM ©   (27.01.08 22:01) [90]
> EInvalidInput надо где то определить
Одна строчка на всю программу. Не вопрос.

> DVM ©   (27.01.08 22:03) [93]
Можно и без Exit. Но многоступенчатый if-then-else вдохновляет еще меньше.

DVM ©   (27.01.08 22:05) [95]
> Более красиво в конструктор передать...
Тоже от задачи зависит. Да и к сабжу не относится.


 
DVM ©   (2008-01-27 22:27) [97]


> Семеныч   (27.01.08 22:22) [96]


> Тоже от задачи зависит.

Я думаю, что не зависит, за редким исключением.

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


 
DVM ©   (2008-01-27 22:28) [98]


> Семеныч   (27.01.08 22:22) [96]


> Можно и без Exit. Но многоступенчатый if-then-else вдохновляет
> еще меньше.

Будучи должным образом отформатирован, он воспринимается без проблем.
И не похож на Goto.


 
Семеныч   (2008-01-27 22:35) [99]

> DVM ©   (27.01.08 22:28) [98]

goto ReturnPoint воспринимается с еще меньшими проблемами, чем двадцатиэтажный if.
:о)


 
DVM ©   (2008-01-27 22:40) [100]


> Семеныч   (27.01.08 22:35) [99]

Ну я ж говорю в [86] - кому как нравится.  Да и против Goto я тоже ничего особого не имею, даже один у меня есть в одной программе - с ним красивее даже.


 
ketmar ©   (2008-01-27 22:57) [101]

>[13] Palladin ©(27.01.08 18:17)
>Это он пошутил… настолько жестко контролировать исключения может только
>тот — кто не использует ничего стороннего, кроме своего…

это он не пошутил. это у него привычка для production code так делать. потому что есть не падать с post mortem dump, то узнать, что там у заказчика произошло — невозможно. максимум, на что стоит раасичтывать — это на невнятное «ну, тут это, какое-то окошко вылезло с непонятными словами, которые я не читал». ни точного описания, ни состояния программы на данный момент обычно добиться не возможно. а в дампе я хоть глянуть могу, что было-то. ну и, натурально, пока я пишу и тестирую, куча «неучтённых» исключений таки находит «последние приюты».

>[78] Семеныч (27.01.08 20:51)
>иалоги — же они по сути своей должны быть модальными.
это идиотская идея. к тому же — а кто тебе виноват, что кнопочка «OK» у тебя разрешена с неверным вводом? сей кнопкой должен управлять валидатор. который тупо не сделает ей Enabled := true, пока юзер не настучит верных данных. это ежели простой диалог. ежели сложный — то по нажатию «OK» мы опять же не закрываемся, а вызываем внешний валидатор, временно задизаблив все диалоговые контролы, если процесс ожидается долгий. а когда валидатор срыгнёт местом с неверным вводом — поясняем юзеру, что с такими консервами консерватория не работает.

зачем тут какие-то исключения и прочие извраты — не ясно.


 
Игорь Шевченко ©   (2008-01-27 23:01) [102]

Семеныч   (27.01.08 22:22) [96]


> Они приходят в дефолтный обработчик. Нормально.


Опять же, от задачи зависит. Мне, например, неплохо бы спозиционироваться на контрол, где что-то неверно, что в дефолтном обработчике сделать несколько напряжнее, чем по месту возникновения ошибки.


 
Игорь Шевченко ©   (2008-01-27 23:03) [103]

ketmar ©   (27.01.08 22:57) [101]

Я мыло отсылаю с ошибкой. Включая стек вызовов, N последних действий пользователя, расположение звезд и плотность потока альфа-частиц.


> сей кнопкой должен управлять валидатор. который тупо не
> сделает ей Enabled := true, пока юзер не настучит верных
> данных. это ежели простой диалог. ежели сложный — то по
> нажатию «OK» мы опять же не закрываемся, а вызываем внешний
> валидатор, временно задизаблив все диалоговые контролы,
> если процесс ожидается долгий. а когда валидатор срыгнёт
> местом с неверным вводом — поясняем юзеру, что с такими
> консервами консерватория не работает.


Примерно так. Только что нельзя делать enabled:=false по первоначальному вызову формы, ибо пугаются.


 
DVM ©   (2008-01-27 23:07) [104]

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


 
Семеныч   (2008-01-27 23:14) [105]

> ketmar ©   (27.01.08 22:57) [101]

> это идиотская идея.

Наоборот. Идиотская идея - это вот что:
- юзер выбирает какую-то запись в каком-то списке и жмет "Изменить";
- выводится немодольный диалог изменения полей этой записи;
- и юзер имеет возможность выбрать другую запись, не закрыв диалога. К какой записи теперь относится диалог - непонятно.

> кнопочка «OK» у тебя разрешена с неверным вводом? сей кнопкой
> должен управлять валидатор. который тупо не сделает ей Enabled
> := true, пока юзер не настучит верных данных.

И бедняга юзер сидит и не понимает, почему у него ОК недоступна. Он же не знает, что TargetName может содержать только буквы и цифры.

> ежели сложный — то по нажатию «OK» мы опять же не закрываемся,
> а вызываем внешний валидатор

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

> зачем тут какие-то исключения и прочие извраты — не ясно.

Нет, дружище, изврат - это как раз то, что ты предлагаешь.


 
ketmar ©   (2008-01-27 23:17) [106]

>[103] Игорь Шевченко ©(27.01.08 23:03)
>Я мыло отсылаю с ошибкой. Включая стек вызовов, N последних действий
>пользователя, расположение звезд и плотность потока альфа-частиц.

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

>Только что нельзя делать enabled:=false по первоначальному вызову формы,
>ибо пугаются.

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

>[104] DVM©(27.01.08 23:07)
>Да не нужны там игры с Enabled

кнопочка «OK» тоже не нужна. да и весь GUI не нужен — есть же консоль, нафига?


 
DVM ©   (2008-01-27 23:19) [107]


> кнопочка «OK» тоже не нужна. да и весь GUI не нужен — есть
> же консоль, нафига?

Не перегибай палку. Я говорил только об Enabled.


 
Семеныч   (2008-01-27 23:23) [108]

> Игорь Шевченко ©   (27.01.08 23:01) [102]

> неплохо бы спозиционироваться на контрол, где что-то неверно,
> что в дефолтном обработчике сделать несколько напряжнее

А это и не надо делать в дефолтном обработчике:

constructor EInvalidUserInput.Create(Control: TWinControl; Message: string);
begin
 Control.SetFocus;
 inherited Create(Message);
end;


procedure TSomeForm.Validate;
begin
 if TargetName = "" then
   raise EInvalidUserInput.Create(TargetNameEdit, "Не задано наименование");
end;


 
ketmar ©   (2008-01-27 23:24) [109]

>[105] Семеныч (27.01.08 23:14)
>- и юзер имеет возможность выбрать другую запись, не закрыв диалога.
а зачем он имеет эту возможность? O_o

>И бедняга юзер сидит и не понимает, почему у него ОК недоступна. Он же не
>знает, что TargetName может содержать только буквы и цифры.

а отчего он это не знает? ты, как автор, забыл сообщить? сообщи.

>И этот внешний валидатор должен каким-то волшебным образом определить
ты бы почитал меня внимательно. ну где я написал, что внешний валидатор должен что-то знать о формах? не знает он о них. для него информацию собрали в кучку и отдали на рассмотрение. заодно не забыли подписаться на событие «я, бляха номер 2857, рассмотрение пришедших данных закончил и имею вам сообщить, что…»

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


 
Семеныч   (2008-01-27 23:35) [110]

> ketmar ©   (27.01.08 23:24) [109]

> а зачем он имеет эту возможность? O_o

А затем, что диалог немодальный. Прикажешь Enabled переключать? Можно, только на фига себе геморрой устраивать? Не проще сделать диалог модальными не иметь никаких проблем?

> а отчего он это не знает? ты, как автор, забыл сообщить? сообщи.

А на фига мне лишние страниц доки писать? Которую он, к тому же  все равно читать не будет. Вот нажмет ОК - тогда все и увидит.

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

Угу. И правила проверки в ту же кучку запихнуть не забыли (а то откуда он узнает, что Дата1 должна быть строго меньше Даты2?). А эти правила еще как-то и формализовать надо - сиди, изобретай способ формализации. Потом пиши все это, потом отлаживай.

Ты прикинул, сколько лишнего геморроя ты предлагаешь поиметь? На фига?


 
sdts   (2008-01-27 23:40) [111]

Почему ветка еще не в "Начинающим"?


 
ketmar ©   (2008-01-27 23:41) [112]

>[110] Семеныч (27.01.08 23:35)
>Не проще сделать диалог модальными не иметь никаких проблем?
не проще. в достаточно сложной программе (а не той, где одна форма да три контрола) модальный диалог перекрывает доступ ко ВСЕМУ фкнуционалу. что в большинстве случаев на редкость идиотично. да возьми хотя б окошки preferences, которые всякие идиоты делают модальными. удобно — аж жуть.

>Угу. И правила проверки в ту же кучку запихнуть не забыли
не забыли, потому что модель — она в курсе, что у неё внутри должно быть и как. а вот GUI как раз об этом знать совершенно не надо.

>Ты прикинул, сколько лишнего геморроя ты предлагаешь поиметь? На фига?
для такой штуки, как «разделение внешнего вида и внутреннего представления данных». в программе с парой форм, как я писал, оно, может, и не надо. но когда программа вырастает — становится мучительно больно от того, что сразу такие вещи друг от друга не отделил.


 
Семеныч   (2008-01-27 23:56) [113]

> ketmar ©   (27.01.08 23:41) [112]

> для такой штуки, как «разделение внешнего вида и внутреннего
> представления данных».

Не сотвори себе кумира. Отделение слоя данных от гуя - штука хорошая, но только до тех пор, пока она не превращается в самоцель.

> становится мучительно больно от того, что сразу такие вещи друг от
> друга не отделил.

При разумном проектировании- не становится. Не сотвори себе кумира.


 
ketmar ©   (2008-01-28 00:20) [114]

>[113] Семеныч (27.01.08 23:56)
это не кумир, а опыт. когда заказчик сам не знает, чего хочет (то есть, всегда) — задолбёшься гуя перебирать. к тому же такое отделение даёт и другие выгоды. можно и в hex-кодах писать, только зачем?

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


 
Игорь Шевченко ©   (2008-01-28 00:54) [115]

Семеныч   (27.01.08 23:23) [108]


>
> constructor EInvalidUserInput.Create(Control: TWinControl;
>  Message: string);
> begin
>  Control.SetFocus;
>  inherited Create(Message);
> end;


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


 
Игорь Шевченко ©   (2008-01-28 00:57) [116]

ketmar ©   (27.01.08 23:17) [106]


> это от юзеров зависит. потом привыкают к тому, что при кривых
> данных у них «OK» не нажмётся. даже благодарят за такую
> фичу.


Они не привыкают потом. Они не покупают сейчас. Между сейчас и потом есть временной интервал.


 
Черный Шаман   (2008-01-28 01:07) [117]


> быстро-быстро сдать и поиметь вечный геморрой с поддержкой.


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


 
ketmar ©   (2008-01-28 01:17) [118]

>[116] Игорь Шевченко ©(28.01.08 00:57)
я обычно пишу то, что уже есть кому продать. так что мне такое сообрежание не очень важно. %-)

>[117] Черный Шаман (28.01.08 01:07)
ну, если ты предпочитаешь кактусы — переубеждать не буду. я предпочитаю, чтобы мне оплачивали не гемор, а работу. заказчики — они тоже, отчего-то, ценят скорость внесения изменений и надёжность. не такие они тупые, как иногда кажется.


 
Семеныч   (2008-01-28 01:23) [119]

> ketmar ©   (28.01.08 00:20) [114]

> это не кумир, а опыт

Ты пропустил одно слово...
:о)

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

Вот разделил ты все. ОК. Заказчик меняет задачу. Поле в таблицу добавилось. Теперь тебе слой данных надо менять? Надо. Гуевый редактор этой таблицы менять надо? Надо. Новое поле в правила проверки добавлять надо? Надо.

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

И что же ты выиграл? Ничего. А лишнего геморроя - поимел.

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

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


 
defunct ©   (2008-01-28 01:31) [120]

> Игорь Шевченко ©   (27.01.08 19:20) [33]
> Ситуацию нельзя исправить никогда.

Иногда можно - попытаться повторить операцию.
И иногда это помогает - пример intermittent bad block на диске.



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

Текущий архив: 2008.03.02;
Скачать: CL | DM;

Наверх




Память: 0.73 MB
Время: 0.026 c
2-1202467900
Artem
2008-02-08 13:51
2008.03.02
listbox и image


2-1201770278
S.T.
2008-01-31 12:04
2008.03.02
Возможно в одном запросе заполнить три DBComboBox-а?


3-1192518920
Александр
2007-10-16 11:15
2008.03.02
Представление информации из баз данных в виде дерева


2-1202059513
sauron
2008-02-03 20:25
2008.03.02
URL


15-1201632004
timeout
2008-01-29 21:40
2008.03.02
UUID компьютера