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

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.72 MB
Время: 0.057 c
8-1175084985
ChinG
2007-03-28 16:29
2008.03.02
Сохранение Canvas


8-1175162015
YadlU
2007-03-29 13:53
2008.03.02
Дата время разность двух дат


3-1192105820
Dush
2007-10-11 16:30
2008.03.02
условие отображения данных в DBGridEh


8-1174744468
VitAngel
2007-03-24 16:54
2008.03.02
Снимок с Вебкамеры


15-1201263477
TUser
2008-01-25 15:17
2008.03.02
Обживаем вин2003: множественность рабочих столов





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский