|
|
|
Assert vs. Exception
|
|||
|---|---|---|---|
|
#18+
Правильно-ли я понимаю, что предусловия каждого метода следует проверять обычным if, и в случае несовпадения выбрасывать exception, а постусловия метода и инвариант класса assert'ом ? А также, верно-ли то, что exception'ы для предусловий следует использовать вместо assert потому, что-бы иметь возможность при использовании этого метода перехватить это исключение и попытаться восстановить работу программы ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.05.2007, 12:21 |
|
||
|
Assert vs. Exception
|
|||
|---|---|---|---|
|
#18+
Попробуйте привести мысли в порядок и сказать то же самое еще раз. Отдельно буду весьма признателен за объяснение, чем EAssertionFailed так уж принципиально отличается от других exception-ов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.05.2007, 14:04 |
|
||
|
Assert vs. Exception
|
|||
|---|---|---|---|
|
#18+
Имеем следующий метод: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. Т.е. меня теперь интересует, где использовать assert, а где exception. Или это типа вообще без разницы ? softwarer Отдельно буду весьма признателен за объяснение, чем EAssertionFailed так уж принципиально отличается от других exception-ов. по-видимому чем-то отличается, раз не является потомком Exception и не ловиться даже всеядным фильтром catch() На мой взгляд, Assert гораздо удобнее и нагляднее (в том числе и для предусловия), чем дурацкий If, но в документации настойчиво советуют использовать именно ArgumentOutOfRangeException, да и в .NET для поимки необработанного исключения применяется делегат Application.ThreadException, который не обращает никакого внимания на Assert Failed, пропуская к пользователю уродливое окно :( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.05.2007, 16:17 |
|
||
|
Assert vs. Exception
|
|||
|---|---|---|---|
|
#18+
heyТ.е. меня теперь интересует, где использовать assert, а где exception. Или это типа вообще без разницы ? Принципиальной разницы нет. Есть некоторое соглашение, общепринятое понимание "что есть assertion и зачем и как оно используется". hey softwarer Отдельно буду весьма признателен за объяснение, чем EAssertionFailed так уж принципиально отличается от других exception-ов. по-видимому чем-то отличается, раз не является потомком Exception и не ловиться даже всеядным фильтром catch() Ну это у кого как. У меня, например, Код: plaintext 1. 2. 3. 4. 5. 6. 7. heyНа мой взгляд, Assert гораздо удобнее и нагляднее (в том числе и для предусловия), чем дурацкий If, но в документации настойчиво советуют использовать именно ArgumentOutOfRangeException, Хм. А кто мешает Вам обойтись без дурацкого if? Кто мешает написать что-нибудь типа Код: plaintext 1. 2. 3. 4. 5. heyда и в .NET для поимки необработанного исключения применяется делегат Application.ThreadException, который не обращает никакого внимания на Assert Failed, пропуская к пользователю уродливое окно :( Вообще-то пользователю обычно дают версию без assert-ов. Еще раз: разница между ними - в предназначении. Exception означает, что ситуация не позволяет выполнить запрошенную операцию, и чаще всего это является "внешней" по отношению к исполняемому коду ошибкой - то ли вызвали с неправильными параметрами, то ли организовали неправильный контекст, то ли еще что-нибудь в этом духе. Assert - это ситуация "внутренней ошибки", "ошибки программирования где-то рядом, в этом самом классе или модуле". Обработать ее, исправить в рантайме как правило невозможно, в некоторых случаях - пересоздав и заново инициализировав объект. Такие проверки принято щедро разбросать по коду и не собирать в release версию. По сути assertion - это миниатюрный юнит-тест. Решение, какая ошибка внешняя, а какая внутренняя - вообще говоря, неформально, зависит от того, что Вы считаете модулем. Скажем, для стандартных коллекций "неправильный индекс" - никак не может быть assertion-ом, это в 99.99% случаев ошибка вызывающего. В то же время если у Вас в классе есть inner class коллекции - в нем тот же самый неправильный индекс запросто может быть именно внутренней ошибкой, assertion-ом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.05.2007, 16:48 |
|
||
|
Assert vs. Exception
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. Глядя на этот исходник абсолютно невозможно сделать выводы о том, какие и где следует толкать исключения. Только исходя из внутренней политики разработок и рассматривая этот модуль в совокупности с другими модулями (контейнерами) можно декларировать требования. Вообще подобные вещи обсуждаются с другими разработчиками-участниками проекта. Тесты утверждений можно ставить щедрой рукой в подозрительных местах, не забывая про возможность видеть результат их работы. Тоесть разрабатываемая "система" должна предусматривать наблюдение за ассертами. В противном случае - они не нужны. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.05.2007, 17:53 |
|
||
|
Assert vs. Exception
|
|||
|---|---|---|---|
|
#18+
softwarer ... спасибо понятно, по большому счету я так и думал - предусловия - exception, постусловия и инварианты - assert. Просто меня сбивает с толку такое разделение, ведь оба они занимаются одним делом - проверкой правильности поведения программы, и не так уж важно с точки зрения всего приложения, вызвана ошибка неверным поведением вызывающего модуля (ведь он просто нарушил контракт - зная, что нужны положительные х, использовал отрицательные, это кстати можно (и нужно) было-бы проверить, перед вызовом), либо неверным поведением внутри модуля, приведшим к неверным результатам. Ну а то, что нельзя перехватить Assert (по крайней мере я пока не знаю, как это сделать в .NET) и показать пользователю нормальное окно с извинениями - это вообще никуда не годиться (может я хочу оставить такие проверки в релизе - если они не отьедают непозволительно большое количество ресурсов, то вообще-то так как раз и рекомендуется поступать), а если такой способ и есть - все равно имхо разделение на exception и assert какое-то исскуственное mayton Глядя на этот исходник абсолютно невозможно сделать выводы о том, какие и где следует толкать исключения ну раз любой открытый метод обязан проверять аргументы на входе, то почему-же не ясно ? или имеете ввиду, что там вместо exception вполне может оказаться assert ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.05.2007, 18:32 |
|
||
|
Assert vs. Exception
|
|||
|---|---|---|---|
|
#18+
hey по большому счету я так и думал - предусловия - exception, постусловия и инварианты - assert. Я этого не говорил. hey Просто меня сбивает с толку такое разделение, ведь оба они занимаются одним делом - проверкой правильности поведения программы, и не так уж важно с точки зрения всего приложения, Пока Вы смотрите с точки зрения всего приложения - неважно. Грань, которую мы обсуждаем, действительно тонкая и нечеткая. По большому счету, между любыми исключительными ситуациями, выглядящими для конечного пользователя как internal error, нет особой разницы. Мало того, те же самые проверки предусловий время от времени хочется убрать ради эффективности. Однако, есть определенная практика. Срабатывание assert-а означает ошибку внутри модуля; получив assert, я автоматом говорю: "Вася, смотри, твой код глюкнул". А получив исключение, я первым делом смотрю, а правильно ли я Васин код вызвал. heyНу а то, что нельзя перехватить Assert (по крайней мере я пока не знаю, как это сделать в .NET) Думаю, ковырнуть Debug.Listeners. Ну или погуглить :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.05.2007, 18:48 |
|
||
|
Assert vs. Exception
|
|||
|---|---|---|---|
|
#18+
softwarer Я этого не говорил значит, я что-то не так понял. Из ваших слов "то ли вызвали с неправильными параметрами, то ли организовали неправильный контекст" я понял, что это про предусловия (а кто, если не они ? Неверные параметры и контекст - самые что ни на есть предусловия), а "ошибки программирования где-то рядом, в этом самом классе или модуле" это и есть постусловие + инвариант + проверки по ходу работы чего-нибудь еще. softwarer Однако, есть определенная практика. Срабатывание assert-а означает ошибку внутри модуля; получив assert, я автоматом говорю: "Вася, смотри, твой код глюкнул". А получив исключение, я первым делом смотрю, а правильно ли я Васин код вызвал. а что собственно помешает мне указать на Васю в случае исключения ? Неужели и в самом деле это все просто практика программирования ? Мне казалось, что имеются более веские причины разделять эти понятия. Вот например если при запросе к БД оборвалась связь - это безусловно исключение, а вот вызов с неправильными параметрами - это нарушение правил работы (ошибка программиста) с модулем. Зачем тут исключение ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.05.2007, 19:52 |
|
||
|
Assert vs. Exception
|
|||
|---|---|---|---|
|
#18+
Обычно утверждениями удобно документировать допушения кода. Те. например: Код: plaintext 1. 2. 3. 4. Но т.к. операции с соединением (т.б. по сети) относятся к внешним факторам (т.е. не зависят от качества ПО), то ошибки соединения надо обрабатывать отдельно, например: Код: plaintext 1. 2. 3. 4. 5. 6. 7. В таком случает даже убрав assert'ы из релиза всё равно будет обработка. А на стадии разработки покажет неверные допушения, и код который нужно изменить. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.05.2007, 10:22 |
|
||
|
Assert vs. Exception
|
|||
|---|---|---|---|
|
#18+
heyНу а то, что нельзя перехватить Assert (по крайней мере я пока не знаю, как это сделать в .NET) и показать пользователю нормальное окно с извинениями - это вообще никуда не годиться (может я хочу оставить такие проверки в релизе - если они не отьедают непозволительно большое количество ресурсов, то вообще-то так как раз и рекомендуется поступать), а если такой способ и есть - все равно имхо разделение на exception и assert какое-то исскуственное Насколько я понимаю, Assert нужен только на этапе отладки, когда вы строите Release версию, все методы классов Debug и Debugger игнорируются, что позволяет повысить производительность приложения. Так что не стоит пытаться перехватить и обработать Assert. Если вам это нужно, используйте Exception. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.05.2007, 10:32 |
|
||
|
Assert vs. Exception
|
|||
|---|---|---|---|
|
#18+
heyИз ваших слов Я назвал яркие типовые случаи, действительно ложащиеся на Ваш взгляд, но не имел в виду ограничиваться только ими, наоборот, хотел сфокусироваться на другом критерии деления, внешнее/внутреннее. heyа что собственно помешает мне указать на Васю в случае исключения ? То, что Вася обидится, если Вы начнете валить все на него раньше, чем проверите отсутствие бревна у себя. heyНеужели и в самом деле это все просто практика программирования ? Безусловно. Я даже больше скажу - и исключения, и assert-ы выросли целиком из практики, никто их специально не придумывал. Просто, когда таких механизмов не было на уровне языка, приходилось писать более или менее уродливый код, реализующий то же доступными средствами. Разумеется, любой механизм можно применить и "не совсем по назначению", бывают случаи, когда это оказывается удобно. Но тем не менее, когда такой вот возникший механизм уже отработан, концептуально вылизан и приспособлен для решения своих задач, чем дальше от них его применяешь - тем более все похоже на ковыряние в правом ухе левой ногой. heyМне казалось, что имеются более веские причины разделять эти понятия. Вот например если при запросе к БД оборвалась связь - это безусловно исключение, а вот вызов с неправильными параметрами - это нарушение правил работы (ошибка программиста) с модулем. Зачем тут исключение ? Хм. Понимаете ли в чем дело, граница - гибкая, ее можно провести там и так, как Вам удобно (с естественными оговорками на командную работу итп). Поэтому та экстремальная позиция, которую занимаете Вы, не является неправильной, можно и так, и каких-то стопроцентных недостатков в ней не назовешь, вопрос в довольно нечетком удобстве. Cкажем, "вызов с неправильными параметрами вроде как ошибка программиста". А что делать, если: 1. Читаем параметры из конфигурационного файла 2. Класс, который читает файл, нафиг не должен знать про смысл этих параметров, его задача - читать файл и запихивать прочитанное в объект, который и будет разбираться со смыслом 3. В случае неверного параметра нужно ругаться, причем не просто так, а "параметр такой-то в файле таком-то не отвечает таким-то требованиям" ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.05.2007, 11:12 |
|
||
|
Assert vs. Exception
|
|||
|---|---|---|---|
|
#18+
Anton. Насколько я понимаю, Assert нужен только на этапе отладки, когда вы строите Release версию, все методы классов Debug и Debugger игнорируются, что позволяет повысить производительность приложения. Так что не стоит пытаться перехватить и обработать Assert. Если вам это нужно, используйте Exception. Во-первых, почитав документацию, сегодня я уже нашел, как ловить Assert'ы в .NET (как и говорил softwarer, нужно копаться в Listener'aх - правда немного неудобно сделано, создать своего потомка от этого класса и переопределить метод Fail(), а имеющийся по умолчанию Listener удалить из коллекции). Во-вторых, Trace'ы не отключаются (по умолчанию) в релизе, так что обрабатывать Trace.Assert'ы все равно надо. В-третих, если тестирование показывает, что снижение производительности от проверок не является значительным, то их отключение - очень странный поступок. softwarer То, что Вася обидится, если Вы начнете валить все на него раньше, чем проверите отсутствие бревна у себя. а причем тут исключение ? Какая разница, что возникло на экране - исключение или assert, ведь смотреть-то надо на его текст, а там будет все написано, кто из нас дурак softwarer Но тем не менее, когда такой вот возникший механизм уже отработан, концептуально вылизан и приспособлен для решения своих задач, чем дальше от них его применяешь - тем более все похоже на ковыряние в правом ухе левой ногой. все-таки не совсем понятно, почему проверка предусловий Exception'ами называется отходом от решения задач приспособленным способом и ковырянием в носу через задницу softwarer вопрос в довольно нечетком удобстве. а также не понятно, почему Exception там удобнее. Как я написал под первой цитатой - все равно надо смотреть на текст сообщения, кроме того, ведь не каждое-же исключение будет являться вашим бревном - обрыв связи с сервером БД уж точно не ваша ошибка softwarer Cкажем, "вызов с неправильными параметрами вроде как ошибка программиста". А что делать, если: 1. Читаем параметры из конфигурационного файла 2. Класс, который читает файл, нафиг не должен знать про смысл этих параметров, его задача - читать файл и запихивать прочитанное в объект, который и будет разбираться со смыслом 3. В случае неверного параметра нужно ругаться, причем не просто так, а "параметр такой-то в файле таком-то не отвечает таким-то требованиям" ? вроде-как это-же один из шаблонов проектирования, когда для чтения пользовательского ввода или файлов применяется фильтр, который разбирается с тем, что прочитал, и либо ругается, либо что-то пытается с этим сделать, после чего подает на вход модулю нормальные данные, удовлетворяющие его (модуля) предусловия. Так что "нафиг не должен знать про смысл этих параметров" - неправильно :) Также не совсем понял, почему вы обозвали позицию "нарушения предусловий, постусловий, инварианта - assert(), а проблемы невозможности выполнения задачи (обрыв связи, не найден файл итп) - исключения" - экстремальной. Мне как раз кажется очень логичной и интуитивно понятной идея размешения Assert'ов там, где возможны ошибки программирования (а неправильный ввод - это именно ошибка: раз уж определили такой контракт с классом, так будьте добры его выполнять), а проблемы, возникающие по вине посторонних лиц, такие как невозможность выделить память - в Еxception'ы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.05.2007, 16:21 |
|
||
|
Assert vs. Exception
|
|||
|---|---|---|---|
|
#18+
hey а неправильный ввод - это именно ошибка следует читать как "а не правильный параметр (не удовлетворяющий заданному контрактом предусловию), поданный на вход модуля - это именно ошибка" ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.05.2007, 16:26 |
|
||
|
Assert vs. Exception
|
|||
|---|---|---|---|
|
#18+
heyа причем тут исключение ? Какая разница, что возникло на экране - исключение или assert, ведь смотреть-то надо на его текст, а там будет все написано, кто из нас дурак Можно, конечно, и так. Как я уже говорил, это вопрос исключительно принятой практики. heyвсе-таки не совсем понятно, почему проверка предусловий Exception'ами называется отходом от решения задач приспособленным способом и ковырянием в носу через задницу Exception-ами или Assert-ами? heyа также не понятно, почему Exception там удобнее. Может быть удобнее. Один из примеров я привел выше. heyвроде-как это-же один из шаблонов проектирования, когда для чтения пользовательского ввода или файлов применяется фильтр, который разбирается с тем, что прочитал, и либо ругается, либо что-то пытается с этим сделать, после чего подает на вход модулю нормальные данные, удовлетворяющие его (модуля) предусловия. Так что "нафиг не должен знать про смысл этих параметров" - неправильно :) Ну если "инкапсуляция" это "неправильно", то в задницу такой шаблон проектирования :) При всей правильности мысли о шаблонах проектирования мне крайне не нравится не так уж редко мелькающая мысль о том, что они могут заменить мозги. Это не так; думать и действовать исходя из этого - все равно что полагать, что автомобиль может заменить водителя. Вы в данном случае ответили поспешно. Можно выделить фильтр, можно не выделять - это отдельный вопрос. В любом случае у нас есть три взаимодействующих объекта: инициатор, ридер и фильтр-либо-целевой-объект, каждый из которых обладает определенными уникальными знаниями, и итогом их работы должно стать выданное инициатором окно типа "ошибка в конфигурационном файле, строка такая-то, параметр такой-то, ошибка состоит в том-то". Для этого использовать Exception во-первых удобно, во-вторых, естественно, несмотря на то, что ошибка вроде бы подходит под Ваше "вызван не с теми параметрами". heyТакже не совсем понял, почему вы обозвали позицию "нарушения предусловий, постусловий, инварианта - assert(), а проблемы невозможности выполнения задачи (обрыв связи, не найден файл итп) - исключения" - экстремальной. Экстремум - это предел, край. Позиция экстремальна, потому что в ней граница между assert-ом и exception-ом задвинута так далеко от некоего "среднего", как только можно; по сути, Вы предлагаете, иметь в программе 99% assert-ов и 1% exception-ов. heyМне как раз кажется очень логичной и интуитивно понятной идея размешения Assert'ов там, где возможны ошибки программирования (а неправильный ввод - это именно ошибка: раз уж определили такой контракт с классом, так будьте добры его выполнять), а проблемы, возникающие по вине посторонних лиц, такие как невозможность выделить память - в Еxception'ы. Эту логику постоянно пытаются реализовать тем или иным образом, например, в дотнете разделили исключения на SystemException и ApplicationException. Но в итоге каждый раз оказывается, что не все так однозначно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.05.2007, 16:52 |
|
||
|
Assert vs. Exception
|
|||
|---|---|---|---|
|
#18+
softwarer Exception-ами или Assert-ами? Exception-ами softwarer Ну если "инкапсуляция" это "неправильно", то в задницу такой шаблон проектирования :) Раз-уж такой шаблон есть и широко используется, то по всей вероятности с инкапсуляцией там все в порядке :) softwarer При всей правильности мысли о шаблонах проектирования мне крайне не нравится не так уж редко мелькающая мысль о том, что они могут заменить мозги. Это не так; думать и действовать исходя из этого - все равно что полагать, что автомобиль может заменить водителя. возможно будете смеяться, но такие автомобили уже есть, я их сам видел по телевизору - они ездят по специальным трассам, где находяться некие метки, на которые ориентируется автопилот автомобиля. Я к примеру нахожу вполне вероятным, что в старости меня будет возить автомобиль, примерно такой-же как возил Шварценеггера в "Вспомнить все" ;) А если по теме - то шаблоны не заменяют мозги, а позволяют избавить их от ненужной работы там, где уже все давно продумано и доказано. Если есть типовая задача - то и решать ее надо типовым способом, а применить мозги тут нужно только в плане анализа - насколько эта задача подпадает под шаблон. softwarer Вы в данном случае ответили поспешно. Можно выделить фильтр, можно не выделять - это отдельный вопрос. В любом случае у нас есть три взаимодействующих объекта: инициатор, ридер и фильтр-либо-целевой-объект, каждый из которых обладает определенными уникальными знаниями, и итогом их работы должно стать выданное инициатором окно типа "ошибка в конфигурационном файле, строка такая-то, параметр такой-то, ошибка состоит в том-то". Для этого использовать Exception во-первых удобно, во-вторых, естественно, несмотря на то, что ошибка вроде бы подходит под Ваше "вызван не с теми параметрами". Давайте-ка более аккуратно: исключение это по определению ситуация, наступление которой мы предполагаем маловероятным, но все-же предвидеть обязаны. Под это определение попадает обрыв связи и отсутствие необходимой памяти. В этой ситуации метод обязан доложить об невозможности выполнения своего контракта "наверх" и умыть руки, потому-что обычно он не в состоянии решить эту проблему (восстановить связь например). Под это определение не попадает нарушение предусловий, потому-что в протестированной системе теоретически это невозможно, и мы не обязаны этого предвидеть. Хотя на практике конечно лучше оставить там на охране Assert и в случае ошибки например вообще прервать выполнение приложения. При чтении файла или пользовательского ввода можно говорить о том, что вероятность поступления неверной информации настолько велика (по сути, поступление верных данных более маловероятно, чем неверных , что мы должны всегда ее проверять (тщательно), и уже поэтому это не должно быть Exception. Я могу согласиться тем не менее, что иногда Exception может оказаться тут "удобным", но насколько это будет "естественно" - не уверен. По-сути, вы просто распихали обязанности верификатора по двум ни в чем не повинным объектам - ридеру файла (или пользовательскому окну) и объекту бизнес логики. Мне не кажется, что они будут вам за это очень благодарны. Теперь ридер или окно (а окон кстати может быть много) должно мало того, что знать об этом объекте, так и еще и брать на себя обязанности по отлову исключения и выводу ошибки на экран. А объект бизнес логики должен теперь проверять и выбрасывать исключения (что хотя конечно мало отличается от Assert, который все равно там должен быть, но вот если потом вы решите при считывании неверного параметра не ругаться сразу, а попытаться конвертировать его в более правильный (напр. "Yes" в "Y"), ваш метод CalculateSales(int items) рискует превратиться в что-нибуть типа Verify_Items_Parameter_And_Correct_It_If_Possible_And_Then_Calculate_Sales_Otherwise_Raise_Exception(int items)) softwarer Позиция экстремальна, потому что в ней граница между assert-ом и exception-ом задвинута так далеко от некоего "среднего", как только можно; по сути, Вы предлагаете, иметь в программе 99% assert-ов и 1% exception-ов. если моя программа и в самом деле не зависит от внешних поставшиков данных типа БД, линий связи и прочей ненадежной среды, то не вижу причин не иметь там максимум 1% Exception'ов, разве это экстрим ? Я и сам часто люблю говорить о "золотой середине", но все-таки зачем насильно уравнивать вещи без надобности ? softwarer Эту логику постоянно пытаются реализовать тем или иным образом, например, в дотнете разделили исключения на SystemException и ApplicationException. Но в итоге каждый раз оказывается, что не все так однозначно. Рихтер уже успел поругать эту идею :) Тем не менее это не сильно касается проблем разделения Assert и Exception ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.05.2007, 21:32 |
|
||
|
Assert vs. Exception
|
|||
|---|---|---|---|
|
#18+
heyРаз-уж такой шаблон есть и широко используется, Кто Вам сказал, что он есть и тем более широко используется? heyто по всей вероятности с инкапсуляцией там все в порядке :) Может все-таки лучше полагаться на то, что видим, а не на "по всей вероятности"? heyвозможно будете смеяться, но такие автомобили уже есть, Не знаю, будете ли Вы смеяться, но подумайте над тем, что я сказал, еще раз. "Автомобиль, который может заменить водителя" - совсем не то же самое, что и "автомобиль, который ездит на автопилоте". heyа применить мозги тут нужно только в плане анализа - насколько эта задача подпадает под шаблон. К сожалению, именно на этом этапе делается неимоверное количество ошибок. heyДавайте-ка более аккуратно: исключение это по определению ситуация, наступление которой мы предполагаем маловероятным, но все-же предвидеть обязаны. ...... Под это определение не попадает нарушение предусловий, потому-что в протестированной системе теоретически это невозможно, и мы не обязаны этого предвидеть. Ну, в том, что касается изречения "в протестированной системе теоретически не может быть ошибок", оно более чем достойно быть увековеченным. Определение довольно спорное, но я бы отметил, что Вы уперлись в то, о чем я говорил в самом первом письме: в то, что Вы считаете модулем. Если Вы считаете модулем приложение в целом, такое рассуждение могло бы быть верным. Если же Вы считаете модулем, например, класс коллекции (усугубляя - класс коллекции, который Вы разработали как компонент на продажу), ситуация вызова с неверным аргументом - как раз "маловероятно, но все же предвидеть обязаны". heyХотя на практике конечно лучше оставить там на охране Assert и в случае ошибки например вообще прервать выполнение приложения. Это, пардон, выдающаяся глупость. Признаться, меня вообще шокирует привычка современных программ падать по любому поводу, но как только Вы побудете в шкуре пользователя, который полчаса набивал данные только для того, чтобы программа упала там, где эти данные вполне можно было спасти (ну хотя бы нажать "сохранить в файл" вместо "сохранить в базу")..... heyПри чтении файла или пользовательского ввода можно говорить о том, что вероятность поступления неверной информации настолько велика (по сути, поступление верных данных более маловероятно, чем неверных , что мы должны всегда ее проверять (тщательно), и уже поэтому это не должно быть Exception. Странное рассуждение. По сути, Вы говорите "то маловероятное, что мы должны предвидеть, это exception, а то более вероятное, что мы должны предвидеть, это уже не exception". С удовольствием покритикую теорию "где именно проходит граница, отделяющая маловероятное от более вероятного". heyПо-сути, вы просто распихали обязанности верификатора по двум ни в чем не повинным объектам - ридеру файла (или пользовательскому окну) и объекту бизнес логики. Простите, Вы сказали какую-то чушь. Во-первых, я наоборот, избавил ридер от обязанностей верификатора. Я свел работу ридера к предельно простому и надежному алгоритму - прочитать данные (то, что он умеет) и передать их в интерфейс потребителя (и его уже не волнует, что это за потребитель, что он понимает, что не понимает). Потребителем может выступить верификатор - который после проверки передаст их в объект бизнес-логики. Может выступить сам объект бизнес-логики. Может выступить например объект отладочной печати - что бы то ни было, ридеру на это наплевать. Это и есть та независимость объектов, которая позволяет строить гибкие и надежные приложения - и сравните это с Вашим предложением, где ридер должен не только знать про существование некоего "верификатора", не только обрабатывать возможность его отсутствия (скажем - нафиг верификатор, если мы подаем данные в модуль печати), но и самое главное - уметь найти верификатор, подходящий к установленному типу объекта-получателя. Для этого есть свои шаблоны, но в целом это безусловно лишняя, вредная связь. Во-вторых, объект бизнес-логики в данном случае - единственный, кто знает, что ему на самом деле нужно. Рассмотрим простой случай: объект дорабатывается, в него добавляется новое свойство. При верификации в сеттере свойства все оказывается очень просто - добавили это свойство и все, все работает, новая строка из конфигурационного файла транзитом через ридер попадает куда нужно и верифицируется. Вы предлагаете добавлять это свойство в два места - собственно в класс бизнес-логики и в класс-верификатор. Это уже ненадежно, уже тонкое место. Более того, Вы обязываете любого, кто работает с классом бизнес-логики, не забывать пользоваться верификатором. Чтение конфиг-файла - хорошо, но в соседнем проекте такого файла может не быть, а тот же самый объект будет инициализироваться в коде. Что это значит? Это значит, что кто-то будет обязан, как последний идиот, писать что-нибудь типа Код: plaintext 1. 2. 3. Замечательный код, идеально подходит в помойку. heyМне не кажется, что они будут вам за это очень благодарны. Теперь ридер или окно (а окон кстати может быть много) должно мало того, что знать об этом объекте, так и еще и брать на себя обязанности по отлову исключения и выводу ошибки на экран. И снова не так. Обязанность ридера - добавить свою информацию к исключению, если оно будет. То есть: если при инициализации объекта происходит исключение, добавить к нему информацию о файле, свойстве и значении (ну и может быть строке файла). Отлов исключений в каждом окне поотдельности - малопонятный мне идиотизм, к сожалению, используемый по умолчанию для программ на java и .net. Впрочем, и там, и там, вполне можно сделать нормально. heyА объект бизнес логики должен теперь проверять и выбрасывать исключения (что хотя конечно мало отличается от Assert, который все равно там должен быть, Он должен это делать в любом случае - иначе он обяжен программиста в каждом месте использования класса явно вызывать верификатор, что антитехнологично. heyно вот если потом вы решите при считывании неверного параметра не ругаться сразу, а попытаться конвертировать его в более правильный (напр. "Yes" в "Y"), ваш метод CalculateSales(int items) рискует превратиться в что-нибуть типа Verify_Items_Parameter_And_Correct_It_If_Possible_And_Then_Calculate_Sales_Otherwise_Raise_Exception(int items)) Звучит неубедительно. Впрочем, я предпочту обратить этот аргумент против Вас: представьте себе, во что превратится Ваш верификатор в этом же случае. Либо ему придется проверять Verify_Items_Parameter_Eigther_Correct_Or_Can_Be_Corrected, а бизнес-объекту затем делать что-нибудь типа If_Parameter_Not_Correct_But_Can_Be_Corrected_Then_Correct_And_Process_Else_Simply_Process, либо, что более идеологично в Вашей модели, Вам придется придумать еще и третий вспомогательный класс - корректор. То есть - обратите внимание - из-за изменения требований к объекту бизнес-логики Вам придется править класс ридера. И это - лучшая иллюстрация "вредной связи". heyразве это экстрим ? Если показатель задвинут на край допустимого диапазона, его значение безусловно экстремально. Не очень понимаю Вашей нервной реакции. heyРихтер уже успел поругать эту идею :) Тем не менее это не сильно касается проблем разделения Assert и Exception Это практически оно и есть. Почти все SystemException-ы - это то, что Вы хотите обрабатывать assert-ами. Не полностью, но почти (особенно учитывая, что AgumentException - это 95% всех ошибок этого класса). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.05.2007, 22:39 |
|
||
|
Assert vs. Exception
|
|||
|---|---|---|---|
|
#18+
softwarer Ну, в том, что касается изречения "в протестированной системе теоретически не может быть ошибок", оно более чем достойно быть увековеченным. Слово “теоретически” здесь у меня применено в смысле “по большому счету”. В обыденной жизни я его всегда применяю только в этом смысле, и не учел того, что в форуме это кого-нибудь может сбить с толку. softwarer Определение довольно спорное, но я бы отметил, что Вы уперлись в то, о чем я говорил в самом первом письме: в то, что Вы считаете модулем. Если Вы считаете модулем приложение в целом, такое рассуждение могло бы быть верным. Если же Вы считаете модулем, например, класс коллекции (усугубляя - класс коллекции, который Вы разработали как компонент на продажу), ситуация вызова с неверным аргументом - как раз "маловероятно, но все же предвидеть обязаны". Это упирается и в мой первый пост. Я прекрасно вижу, что все поставляемые библиотеки выбрасывают исключения при неверных входных параметрах, и этот подход рекомендуется при разработках библиотек повторного использования. Мне этот подход не кажется правильным и это является причиной появления в этом форуме моего вопроса. Пока-что в ваших объяснениях я увидел только смутное очертания утверждения “просто так везде принято”. Почему так принято, я не понял. softwarer Это, пардон, выдающаяся глупость. Признаться, меня вообще шокирует привычка современных программ падать по любому поводу, но как только Вы побудете в шкуре пользователя, который полчаса набивал данные только для того, чтобы программа упала там, где эти данные вполне можно было спасти (ну хотя бы нажать "сохранить в файл" вместо "сохранить в базу")..... Softwarer, я-бы попросил вас не делать необоснованных и нелепых выводов, да еще и публиковать их в бесцеремонной форме. Вы там слово “например” что-ли не заметили ? И с чего вы взяли, что “прерывание выполнения приложения” тождественно равно “немедленно убить процесс” ? И с какими-это из современных программ вы работаете, если все они падают от малейшего дунавения ветра, уничтожая вашу бесценную информацию ? Современные офисные пакеты пытаются восстановить данные, даже будучи вырубленными Reset’ом. Я-уж молчу про “"сохранить в файл" вместо "сохранить в базу"”. Невозможность сохранения в БД как раз и поднимает исключение (а не Assert, о чем я написал наверно уже раз 15), подразумевая таким образом возможность для приложения не только не падать, но и нормально продолжать работу. softwarer Странное рассуждение. По сути, Вы говорите "то маловероятное, что мы должны предвидеть, это exception, а то более вероятное, что мы должны предвидеть, это уже не exception". С удовольствием покритикую теорию "где именно проходит граница, отделяющая маловероятное от более вероятного". Вы не поняли, о чем я говорил. Exception – это “маловероятное, но обязательное к проверке”. Даже если программа полностью корректна, то ошибка соединения обязана быть предусмотрена. Assert – это нарушение контракта или нормального течения работы метода. Это является ошибкой программирования и при обнаружении обязано быть исправленным. Кроме того, в прошлом посте я не сделал ударения (и вы благополучно это пропустили) на том важном атрибуте исключения, как неспособность метода, где оно возникло, справиться с ним. Именно поэтому он возбуждает исключение, которое передается вызывающему методу, а уж тот решает, что с ним делать – обработать или подняв уровень абстракции передать еще выше. А при получении неверного параметра имхо все гораздо проще – к выполнению тела программы вообще нельзя приступать, налицо ошибка программирования. Которую исправлять нужно, а не играться с уровнями абстракции … softwarer Во-первых, я наоборот, избавил ридер от обязанностей верификатора. Я свел работу ридера к предельно простому и надежному алгоритму - прочитать данные (то, что он умеет) и передать их в интерфейс потребителя (и его уже не волнует, что это за потребитель, что он понимает, что не понимает). Потребителем может выступить верификатор - который после проверки передаст их в объект бизнес-логики. Может выступить сам объект бизнес-логики. Может выступить например объект отладочной печати - что бы то ни было, ридеру на это наплевать. Это и есть та независимость объектов, которая позволяет строить гибкие и надежные приложения - и сравните это с Вашим предложением, где ридер должен не только знать про существование некоего "верификатора", не только обрабатывать возможность его отсутствия (скажем - нафиг верификатор, если мы подаем данные в модуль печати), но и самое главное - уметь найти верификатор, подходящий к установленному типу объекта-получателя. Для этого есть свои шаблоны, но в целом это безусловно лишняя, вредная связь. Объясните мне пожалуйста разницу между вашим верификатором, и моим. А то простите я не понял, почему ридер->верификатор->объект в моем случае хуже чем ридер->верификатор->объект в вашем. softwarer Во-вторых, объект бизнес-логики в данном случае - единственный, кто знает, что ему на самом деле нужно. Рассмотрим простой случай: объект дорабатывается, в него добавляется новое свойство. При верификации в сеттере свойства все оказывается очень просто - добавили это свойство и все, все работает, новая строка из конфигурационного файла транзитом через ридер попадает куда нужно и верифицируется. Вы предлагаете добавлять это свойство в два места - собственно в класс бизнес-логики и в класс-верификатор При изменении интерфейса класса это безусловно влияет на взаимодействующие с ним классы. softwarer Более того, Вы обязываете любого, кто работает с классом бизнес-логики, не забывать пользоваться верификатором Не знаю, какой верификатор вы имеете в виду, но уж точно не мой. Любой другой объект ну ни как не обязан пользоваться фильтром, а может напрямую вызывать этот объект. Вы явно говорите про что-то другое, иначе как объяснить появление метода If_Parameter_Not_Correct_But_Can_Be_Corrected_Then_Correct_And_Process_Else_Simply_Process, которым дескать обязан обладать мой объект бизнес-логики ;) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.05.2007, 21:40 |
|
||
|
Assert vs. Exception
|
|||
|---|---|---|---|
|
#18+
heyСлово “теоретически” здесь у меня применено в смысле “по большому счету”. Если так, это вышибает почву из-под Вашего "не обязаны предвидеть". Как только мы признаем наличие "малого счета", придется признать и "либо обязаны предвидеть, либо приложение будет некачественным". heyЭто упирается и в мой первый пост. Я прекрасно вижу, что все поставляемые библиотеки выбрасывают исключения при неверных входных параметрах, и этот подход рекомендуется при разработках библиотек повторного использования. Мне этот подход не кажется правильным А что же им делать? Они не обладают информацией о контексте, которая позволила бы им принять иное решение. Скажем, just for example, Вы - автор библиотеки - не можете полагаться на то, что кому-нибудь из Ваших пользователей не взбредет в голову написать нечто типа Код: plaintext 1. 2. 3. 4. 5. heyПока-что в ваших объяснениях я увидел только смутное очертания утверждения “просто так везде принято”. Почему так принято, я не понял. Хм. Мне кажется, Вам мешает то, что Вы считаете Exception и Assert принципиально разными вещами. В действительности - достаточно давно придумали использовать подкласс исключений, называемых Assert, для решения определенной задачи. Вам кажется , что этот класс был бы более удобен для решения несколько иного класса задач (будем считать, более широкого). Это вопрос всего лишь понимания слов. Если Вам (и вашей команде) будет так удобнее - да наздоровье, берлинской стены здесь никто не возводит. Вдобавок, есть ощущение, что это кажется обусловлено отсутствием для исключений синтаксиса а-ля assert, того, который я Вам предложил добавить самому. heySoftwarer, я-бы попросил вас не делать необоснованных и нелепых выводов, да еще и публиковать их в бесцеремонной форме. Вы там слово “например” что-ли не заметили ? Приведенный Вами пример меня и шокировал. heyИ с чего вы взяли, что “прерывание выполнения приложения” тождественно равно “немедленно убить процесс” ? Да какая вообще разница, сколь тождественно? Какого хрена "прерывать выполнение" приложения, которое запросто может работать? Допустим, у приложения в силу неведомых причин выпадает assert на функции пятого уровня значимости - например, отражении в статусбаре времени выполнения текущей операции. И что по-Вашему, этого достаточно, чтобы при любой попытке выполнения операции "прерывать выполнение приложения"? Типичный пример эскалации мухи в слона. Технология программирования призвана решать строго обратную задачу - задачу устойчивости. Главное, что программа может делать со своими ошибками - минимизировать их последствия. И самочинно "прерывать выполнение приложения" можно в одном-единственном случае - при наличии уверенности, что "продолжение выполнения" еще более усугубит ситуацию. heyИ с какими-это из современных программ вы работаете, если все они падают от малейшего дунавения ветра, уничтожая вашу бесценную информацию ? В последний раз этим отличилась Visual Studio 2005. heyНевозможность сохранения в БД как раз и поднимает исключение (а не Assert, о чем я написал наверно уже раз 15), Я недостаточно четко проговорит этот момент, но и Вы, если не затруднит, пытайтесь таки понять сказанное, а не "первую неправильную версию, которая пришла Вам в голову". Я не сказал, что все происходит "из-за невозможности сохранения в БД". А имел в виду примерно следующую ситуацию - выпадает Assert во время сохранения в БД. Выпадает на чем угодно, например на том же неправильном доступе к коллекции. Понятно, что в этом случае невозможно сохранить в БД - продолжать операцию после такого нарушения невозможно. Но это не значит, что программу нужно немедленно вырубить, как предложили Вы. В такой ситуации программа может продолжить работу, например, велика вероятность того, что кнопка "сохранить в файл" таки сработает. heyВы не поняли, о чем я говорил. Exception – это “маловероятное, но обязательное к проверке”. Даже если программа полностью корректна, то ошибка соединения обязана быть предусмотрена. Assert – это нарушение контракта или нормального течения работы метода. Боюсь, это Вы не поняли того, что я сказал. Потому что кроме процитированной трактовки exception-а Вы сказали, что "при чтении файла или пользовательского ввода вероятность ошибки столь велика, что это уже не exception". Вот я и спрашиваю - что же это тогда, и как Вы собираетесь проводить границу между "маловероятным" и "более чем маловероятным". heyКроме того, в прошлом посте я не сделал ударения (и вы благополучно это пропустили) на том важном атрибуте исключения, как неспособность метода, где оно возникло, справиться с ним. Этот атрибут является общим для почти любой ошибочной ситуации, я бы сказал, для всех, которые мы обсуждали. Поэтому действительно не вижу причин специально его выделять. heyИменно поэтому он возбуждает исключение, которое передается вызывающему методу, а уж тот решает, что с ним делать – обработать или подняв уровень абстракции передать еще выше. А при получении неверного параметра имхо все гораздо проще – к выполнению тела программы вообще нельзя приступать, налицо ошибка программирования. Которую исправлять нужно, а не играться с уровнями абстракции … У меня такое ощущение, что Вы уже слегка забыли, о чем мы говорим. Я наталкиваю Вас на тот момент, что "получение неверного параметра - ошибка программирования", и в то же время, параметр может быть зашит не константой в приложении, а так или иначе приходить из внешних источников (конфигурационный файл - самый простой пример), и в этом случае это уже не "ошибка программирования", а "ситуация, при которой нужно выдать пользователю вменяемую диагностику, что именно не устраивает, дабы он мог откорректировать этот внешний источник либо иначе решить проблему без какой-либо модификации программы". Различить эти ситуации на уровне программирования бизнес-объекта невозможно. Базовый принцип модульности - объект не должен зависеть от того, кто его вызывает. Соответственно, автор бизнес-объекта не может сказать "ну это ошибка программирования, assert-ная ситуация". heyОбъясните мне пожалуйста разницу между вашим верификатором, и моим. А то простите я не понял, почему ридер->верификатор->объект в моем случае хуже чем ридер->верификатор->объект в вашем. Вопрос, похоже, свидетельствует о некоем непонимании между нами. Давайте сделаем откат и попробуем потщательнее. Итак, изначально я говорил о некоторой системе инициатор->ридер->какой-то-объект. В ней постулировалось следующее: 1. Ридер читает некий файл, в корректности информации в котором мы не уверены, и передает все прочитанное объекту. 2. В случае, если объект не в состоянии принять данные, пользователь должен получить информацию, сочетающую сообщение из объекта (что за ошибка) и информацию из ридера (что за файл). Выдать соответствующее сообщение - по идее, функция инициатора (или чего-то за инициатором). Я привел это как пример взаимодействия, при котором исключение является прямым, удобным и естественным механизмом, которое позволит объекту и ридеру передать информацию об ошибке инициатору. Таким образом я попытался обосновать то, что объект должен выкидывать исключение при ошибке во входных параметрах, поступающих от ридера. Вы сказали, что для этого следует применить паттерн с верификатором. Не знаю, какой именно паттерн Вы имели в виду, принципиально есть две схемы подключения: Код: plaintext и Код: plaintext 1. 2. 3. Не так важно, какая именно схема будет выбрана, важно на самом деле следующее: либо объект бизнес-логики виден снаружи, доступен непосредственно, либо верификатор полностью закрывает его собой. Первый вариант неудачен, что я обосновываю различными приведенными примерами. Если так, значит любой, кто знает об объекте, должен также постоянно помнить о том, что работать надо не напрямую, а через верификатор (или еще хуже - половина действий напрямую, половина с использованием верификатора). Второй же вариант - как раз та схема, с которой мы начали. Практически получается следующее: Код: plaintext 1. 2. 3. 4. 5. В этом случае, выделять ли верификатор, как именно его использовать - внутреннее дело "некоего объекта", ни ридер, ни кто-то другой об этом не знает и не думает. Именно эту схему я полагаю правильной и пытаюсь обосновать. heyНе знаю, какой верификатор вы имеете в виду, но уж точно не мой. Любой другой объект ну ни как не обязан пользоваться фильтром, а может напрямую вызывать этот объект. :(( То есть Вы полагаете нормальным взаимодействие, при которой кто-то может напрямую вызвать не защищенный проверками объект? Давайте еще раз. Сконструируем предельно простой случай: объект с одним свойством. Я предлагаю примерно следующее решение (которое, как Вы говорите, рекомендуется в литературе): Код: plaintext 1. 2. 3. 4. 5. (прошу прощения за возможные синтаксические ошибки, не особо владею C#. Вы говорите о том, что надо выделить верификатор. Учитывая возможность вызова напрямую, которую Вы упомянули, я вижу три варианта: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. Что касается этих вариантов: 1. Просто ненадежен. При прямом обращении класс легко ломается, и это никак не контролируется. 2. Одни и те же проверки приходится делать в двух местах. Классическое копирование кода, со всеми его недостатками. 3. В принципе нормально, но становится непонятно - а нафига нужен этот верификатор. Кому будет хуже, если проверку запихать напрямую в сеттер? heyВы явно говорите про что-то другое, иначе как объяснить появление метода If_Parameter_Not_Correct_But_Can_Be_Corrected_Then_Correct_And_Process_Else_Simply_Process, которым дескать обязан обладать мой объект бизнес-логики ;) Хм. Похоже, с этой аналогией мы совсем перестали понимать друг друга. Предлагаю не выяснять, что мы хотели сказать этими жуткими методами, выше уже все сказано. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.05.2007, 23:32 |
|
||
|
Assert vs. Exception
|
|||
|---|---|---|---|
|
#18+
softwarer Если так, это вышибает почву из-под Вашего "не обязаны предвидеть". Как только мы признаем наличие "малого счета", придется признать и "либо обязаны предвидеть, либо приложение будет некачественным". На мой взгляд, есть важная разница между ошибкой доступа к серверу, потому-что он недоступен, и ошибкой в методе, потому-что его хреново тестировали. Предвидеть обязаны в обоих случаях: В первом) выбросить исключение, а вызывающий объект должен уметь поймать это исключение. Т.е. вызывающий объект как-бы говорит: выполняй метод, но если сервер отключен, то скажи мне об этом, а я дальше разберусь. Во втором) выбросить Assert. Выбрасывать исключение нелогично, и уж тем более нелогично программировать вызывающий объект на отлов этого исключения. Прямо смешно, если вызывающий объект говорит: выполняй метод, а если я тебе вдруг вместо положительного числа дал отрицательное, то скажи мне, а я дальше разберусь 8-). softwarer Хм. Мне кажется, Вам мешает то, что Вы считаете Exception и Assert принципиально разными вещами не принципиально разными, но разными. Выбрасывание исключения подразумевает, что его кто-то будет ловить. Assert такого не подразумевает. Имхо разница на лицо. softwarer Приведенный Вами пример меня и шокировал. Вы легкошокируемый человек. Правда все равно не понимаю, что именно там шокирующего, тем более что вы и сами не отрицаете возможность прервать программу в определенных случаях. softwarer Да какая вообще разница, сколь тождественно? Какого хрена "прерывать выполнение" приложения, которое запросто может работать? Допустим, у приложения в силу неведомых причин выпадает assert на функции пятого уровня значимости - например, отражении в статусбаре времени выполнения текущей операции. И что по-Вашему, этого достаточно, чтобы при любой попытке выполнения операции "прерывать выполнение приложения"? Типичный пример эскалации мухи в слона. Технология программирования призвана решать строго обратную задачу - задачу устойчивости. Главное, что программа может делать со своими ошибками - минимизировать их последствия. И самочинно "прерывать выполнение приложения" можно в одном-единственном случае - при наличии уверенности, что "продолжение выполнения" еще более усугубит ситуацию Если вы уверены, что программа в состоянии продолжать работу, так запишите ошибку в лог-файл, и работайте себе дальше, я-же не против :) softwarer Боюсь, это Вы не поняли того, что я сказал. Потому что кроме процитированной трактовки exception-а Вы сказали, что "при чтении файла или пользовательского ввода вероятность ошибки столь велика, что это уже не exception". Вот я и спрашиваю - что же это тогда, и как Вы собираетесь проводить границу между "маловероятным" и "более чем маловероятным". Дело вовсе не в том, где пролегает эта граница, а том, что вызывает ошибку, и соответственно в разных путях ее преодоления. softwarer Я наталкиваю Вас на тот момент, что "получение неверного параметра - ошибка программирования", и в то же время, параметр может быть зашит не константой в приложении, а так или иначе приходить из внешних источников (конфигурационный файл - самый простой пример), и в этом случае это уже не "ошибка программирования", а "ситуация, при которой нужно выдать пользователю вменяемую диагностику, что именно не устраивает, дабы он мог откорректировать этот внешний источник либо иначе решить проблему без какой-либо модификации программы". Различить эти ситуации на уровне программирования бизнес-объекта невозможно. Базовый принцип модульности - объект не должен зависеть от того, кто его вызывает. Соответственно, автор бизнес-объекта не может сказать "ну это ошибка программирования, assert-ная ситуация". Вот если с этой ситуацией разбирается непосредственно бизнес-объект (без встроенного верификатора), то действительно невозможно. Поэтому это и является работой верификатора, который должен сначала изучить поступаемые из файла данные, а уж затем решить, что с ними делать - посылать в объект или выводить ругательное окно пользователю. softwarer Итак, изначально я говорил о некоторой системе инициатор->ридер->какой-то-объект. В ней постулировалось следующее: ... Понятно. Фактически вы используете исключение как способ сказать инициатору, что в файле находиться недопустимый параметр. Что-ж, позвольте тогда спросить, почему вы не хотите для этой цели использовать сообщения ? Зачем использовать исключение, что-бы просто сказать что-то другому объекту ? В моей версии существует бизнес-объект (второй вариант указанный вами): Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. Предполагается получать параметр myValue как из файла, так и из другого объекта. При чтении из файла, используется верификатор. При получении неверного параметра он отсылает соответствующее сообщение классу, ответственному за отображение ошибки, либо в простейшем случае вообще сам это сообщение выводит на экран. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. При получении из другого объекта, никакого верификатора не нужно, потому-что вызывающий объект обязан быть в курсе ограничений интерфейса объекта BusinessObject. Да, здесь есть нехороший недостаток - создание еще одной сущности и дублирование проверок. Не желая быть снова обвиненным вами в эктремизме скажу, что вероятно в некоторых случаях исключения действительно будут лучше. Но, все-таки давайте посмотрим с другой точки зрения. Во-первых, проверки могут оказаться тяжеловесными. Тогда в моей версии я просто отключу Assert в бизнес объекте и проверки будут производиться только для вызовов на основе чтения из конфиг-файла. Во-вторых, получение из конфиг-файла отрицательного значения вовсе не обязательно должно заканчиваться сообщением пользователю. Возможно достаточно просто свести это значение к ближайшему допустимому (например к единице). В тоже время, получение отрицательного значения из другого объекта свидетельствует об ошибке и как-то должно обработаться. Или к примеру, при получении отрицательного значения поле BusinessObject.MyValue вообще не надо трогать, а оставить то значение, которое оно имеет на текущий момент. Имхо, лучше всю всю эту логику вынести за пределы BusinessObject, так как она его по-сути не касается. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2007, 18:02 |
|
||
|
Assert vs. Exception
|
|||
|---|---|---|---|
|
#18+
heyНа мой взгляд, есть важная разница между ошибкой доступа к серверу, потому-что он недоступен, и ошибкой в методе, потому-что его хреново тестировали. Где-то это различие важно, где-то не важно. heyВо втором) выбросить Assert. Выбрасывать исключение нелогично, и уж тем более нелогично программировать вызывающий объект на отлов этого исключения. Только потому, что Вы не ощущаете следующий простой принцип: "Программа должна работать". Представьте себе любой сервер, любой сервис, скажем тривиальную рассылку клиентам поздравлений с днем рождения. Вполне может быть, что при отправке почты на домен, just say, myname.org, в силу любой возможной особенности сендер падает с assert-ом. Так вот: это совершенно не значит, что несколько десятков, сотен или тысяч других клиентов должны на неопределенный срок остаться без поздравлений. Напротив, по какой бы причине отправка не упала, эта ситуация должна быть корректно обработана (допустим - отметить недоставленное сообщение в БД, отправить сообщение об ошибке админам, нормально обрабатывать другие сообщения, периодически пытаться перепослать это). heyВыбрасывание исключения подразумевает, что его кто-то будет ловить. Совершенно не обязательно - если под "кто-то" не имеется в виду "хандлер самого верхнего уровня, вся функция которого - вывести сообщение об ошибке и не дать программе молча упасть". Ну а такой хандлер ловит и ассерты (точнее, должен ловить - иное будет махровым непрофессионализмом). heyВы легкошокируемый человек. Да нет, вообще говоря. Это вопрос исключительно точки зрения - типа как один человек говорит "всю жизнь курю - никто еще так не реагировал", а другой - "первый раз встречаю человека, прикуривающего на пороховом складе". heyЕсли вы уверены, что программа в состоянии продолжать работу, так запишите ошибку в лог-файл, и работайте себе дальше, я-же не против :) А вот для этого и надо ловить assert-ы. Точнее будет сказать так: и вот именно в этом месте нет никакой разницы между assert-ом и "исключением в Вашем понимании". hey softwarerВот я и спрашиваю - что же это тогда, и как Вы собираетесь проводить границу между "маловероятным" и "более чем маловероятным". Дело вовсе не в том, где пролегает эта граница, а том, что вызывает ошибку, и соответственно в разных путях ее преодоления. Ошибку в обоих случаях вызывает непредсказуемая внешняя среда - в одном случае, например, админ, который потушил сервер БД, в другом случае тот же админ, который сделал опечатку в конфиг-файле. В чем разница? Итак, где пролегает граница? heyВот если с этой ситуацией разбирается непосредственно бизнес-объект (без встроенного верификатора), то действительно невозможно. Поэтому это и является работой верификатора, Во-первых, откуда Вы взяли "без встроенного верификатора"? Я ни про что такое не говорил. heyкоторый должен сначала изучить поступаемые из файла данные, а уж затем решить, что с ними делать - посылать в объект или выводить ругательное окно пользователю. Во-вторых, "выводить ругательное окно" - совершенно не функция верификатора. Он в этом некомпетентен. Дело верификатора - высказать претензии, а кто и как их обработает - вопрос вызывающему объекту. heyПонятно. Фактически вы используете исключение как способ сказать инициатору, что в файле находиться недопустимый параметр. Нет, не так. Я использую исключение как способ сказать инициатору, что операция "чтение конфигурационного файла" закончилась неудачей. При этом я хочу передать в исключении дополнительную диагностическую информацию. Кто и как будет ее использовать - в общем-то, бизнес-объекту без разницы; скажем, инициатор может использовать ее для того, чтобы открыть в редакторе нужный конфигурационный файл, поставить курсор в место ошибки и сказать админу: исправляй. heyЧто-ж, позвольте тогда спросить, почему вы не хотите для этой цели использовать сообщения ? Зачем использовать исключение, что-бы просто сказать что-то другому объекту ? Хм. Знаете, есть такой принцип: "если что-то выглядит как утка, плавает как утка и крякает как утка, то это утка". Так вот: если мне нужно некоторое "сообщение", которое, во-первых, прервет текущую последовательность исполнения программы, во-вторых, доставит информацию не известному заранее "инициатору", проскочив транзитом через тех вызывающих, которые не хотят это сообщение получить - то это "сообщение" называется "исключение", и пытаться использовать в этом месте что-то другое - мягко говоря, нетехнологично. heyВ моей версии существует бизнес-объект (второй вариант указанный вами): ok. По поводу аргументов "против" мы согласны, осталось выяснить, что хорошего мы получим, за что Вы предлагаете платить такую цену. heyВо-первых, проверки могут оказаться тяжеловесными. Тогда в моей версии я просто отключу Assert в бизнес объекте и проверки будут производиться только для вызовов на основе чтения из конфиг-файла. Я согласен с поставленной задачей, но не с решением и предполагаемыми из него выводами. Во-первых, тут нет никакой разницы между assert и exception (надеюсь, Вы в курсе, как реализовано "отключу assert". Ну а во-вторых, верификатор здесь - менее удачное решение, нежели "флаг в бизнес-объекте, включающий или отключающий проверки". Почему менее удачное: 1. Флаг не требует дублирования кода. В частности, не может возникнуть ситуация "в бизнес-объект добавили некоторую проверку, а продублировать ее в верификатор забыли". 2. Флаг можно сделать включенным по умолчанию - и его потребуется явно отключать там, где программист сочтет это безопасным. Наоборот, в Вашей схеме проверки окажутся "по умолчанию отключены", и программист должен будет специально позаботиться - использовать верификатор - для того, чтобы эти проверки включить. heyВо-вторых, получение из конфиг-файла отрицательного значения вовсе не обязательно должно заканчиваться сообщением пользователю. Возможно достаточно просто свести это значение к ближайшему допустимому (например к единице). В тоже время, получение отрицательного значения из другого объекта свидетельствует об ошибке и как-то должно обработаться. Крайне спорное рассуждение, я бы даже сказал, идеологически ложное. По сути Вы говорите следующее: объект должен вести себя по-разному в зависимости от того, кто его вызвал. Это нарушает базовый принцип модульности. Разумеется, подобная постановка задачи возможна, но зависит они никак не от того, идут ли данные из файла или откуда-нибудь еще. Наиболее естественно в такой ситуации сделать два метода, SetValue и SetCorrectedValue, и в каждом месте вызывать тот из них, который соответствует требованиям задачи. heyИмхо, лучше всю всю эту логику вынести за пределы BusinessObject, так как она его по-сути не касается. Я бы сказал, остальных она касается еще меньше. Автор BusinessObject вполне может, если захочет, вынести это в некий отдельный внутренний класс (не в смысле inner, а в смысле internal), и таким образом отделить "суть бизнес-объекта" от "вспомогательного кода". Он может дать некий дополнительный интерфейс для управления этими проверками, включения-выключения коррекции итп, если это нужно. Однако, признаться, удобства двух публичных классов - бизнес-объекта и верификатора - я пока не прочувствовал. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.05.2007, 22:37 |
|
||
|
Assert vs. Exception
|
|||
|---|---|---|---|
|
#18+
У вас очень длиные посты, сорри я их не осилил. Хочу свои мысли привести по поводу assert-ов в java, думаю в .net ситуация должна быть аналогичная. Проверять предуслувия через assert не есть правильно. У метода есть контракт и этот контракт должен быть постоянным. Assert`ы можно отключать в runtime и отключив ваш код перестает выполнять свой контракт. "Мусор на входе, мусор на выходе" - это плохой стиль программировния. простой пример вы проверяете в setter методе что аргумент не null. Код: plaintext 1. 2. 3. Если проверяка будет реализована через assert, то при отключенных assert`ах этот код выполниться (без каких либо проблем) и переведет вашу систему в некорректное состояние. И потом далее при первом обращении вы получите NullPointerException, а когда получите это еще большой вопрос. Так что если вы пишите библиотеку не только для себя, то так проверять входные параметры не следует. Пример как мне кажется правильного использования assert`ов. Вы пишите код для нахождения обратной матрицы, ну и assert что исходная * результат = единичная матрица. (т.е. просто проверка инвариантов). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.05.2007, 09:35 |
|
||
|
Assert vs. Exception
|
|||
|---|---|---|---|
|
#18+
vas0Проверять предуслувия через assert не есть правильно. У метода есть контракт и этот контракт должен быть постоянным. Assert`ы можно отключать в runtime и отключив ваш код перестает выполнять свой контракт. "Мусор на входе, мусор на выходе" - это плохой стиль программировния. Я во многом согласен с Вами, однако, отмечу пару моментов. Во-первых, хотя лично я полагаю, что хороший код - тот, который корректно работает в любых условиях (и если угодно, имеет соответствующий контракт), не так уж редка и другая точка зрения; в частности, если пороетесь в архивах форума, обнаружите, что моя ругань на java имеет одной из причин именно обилие решений, нарушающих этот принцип. Я не хочу сказать, что точка зрения "вызывайте меня только так, иначе получите кирдык" правильна, но она достаточно распространена. Ну а наиболее важный момент заключается в том, что подобные проверки нередко стоит отключать из-за соображений эффективности. Если приложение хорошо оттестировано, элиминация ряда проверок из release build вполне разумна. Скажем, если посмотреть на Ваш пример - в общем-то не так важно, вылетит ли из метода assert violation или null pointer exception, обрабатывать их нужно одинаково. Согласен, null pointer несколько хуже - может проявиться в другом месте, испортить состояние объекта итп - но разница тут уже количественная, имеет смысл считать, стоит ли игра свеч. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.05.2007, 10:39 |
|
||
|
Assert vs. Exception
|
|||
|---|---|---|---|
|
#18+
В принципе согласен со softwarer'ом. Просто мне кажется слишком длинные объяснения запутывают исходное определение. Если подходить с точки зрения практики (сделаем лишь бы работало) Изначально assert и другие исключения ничем не отличаются - они просто говорят, что что-то не так мол разбирайся. Разница только в том, что assert'ы можно легко отключать. Соответсвенно их не стоит ставить туда, где проверка нужна в любом случае. Если подходить с точки зрения теории (сделаем как надо) То assert используется только в "незашищенных" участках, для регистрации некоректного поведения в процессе разработки, а также для документирования допущений кода. Данные факторы весомы особенно когда проект изменчив (либо предполагается его продолжительная поддержка) либо когда над одним проектом работают несколько разработкиков. Возможно в такой среде нужно будет выделить несколько уровней защищенности. Дополнительно возможно разработчик решит считать небезопасным код коллег, хотя всё это может относится к сугобо внутренней закрытой реализации. Если отключение assert'ов не предполагается, то разницы между ними и "обычными" исключениями - разве только в синтаксисе (что легко решаемо). Но опять таки всегда проверять всё не эфективно. А как известно одна из главных проблем программирования - преждевременная оптимизация. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.05.2007, 12:13 |
|
||
|
Assert vs. Exception
|
|||
|---|---|---|---|
|
#18+
softwarer Только потому, что Вы не ощущаете следующий простой принцип: "Программа должна работать". Представьте себе любой сервер, любой сервис, скажем тривиальную рассылку клиентам поздравлений с днем рождения. Вполне может быть, что при отправке почты на домен, just say, myname.org, в силу любой возможной особенности сендер падает с assert-ом. Так вот: это совершенно не значит, что несколько десятков, сотен или тысяч других клиентов должны на неопределенный срок остаться без поздравлений. Напротив, по какой бы причине отправка не упала, эта ситуация должна быть корректно обработана (допустим - отметить недоставленное сообщение в БД, отправить сообщение об ошибке админам, нормально обрабатывать другие сообщения, периодически пытаться перепослать это). а почему вы исходите из того, что при выпавшем Assert приложение придется закрыть ? Вовсе не обязательно. Есть разные виды assert'а, например в .NET в классе Trace есть метод WriteLineIf(), который можно заставить просто записать ошибку в ваш лог-файл. Собственно даже сам метод Fail() можно переопределить так, что он будет только записывать информацию в лог и все. softwarer Совершенно не обязательно - если под "кто-то" не имеется в виду "хандлер самого верхнего уровня, вся функция которого - вывести сообщение об ошибке и не дать программе молча упасть". Ну а такой хандлер ловит и ассерты (точнее, должен ловить - иное будет махровым непрофессионализмом). exception поднимается из метода, где появился и до тех пор, пока кем-нибудь не обработается, хотя-бы тем-же глобальным хуком на необработанные исключения в конечном приложении. Поэтому обработается в любом случае. А Assert кстати в том-же .NET надо ловить уже другим методом - листенером. softwarer А вот для этого и надо ловить assert-ы. Точнее будет сказать так: и вот именно в этом месте нет никакой разницы между assert-ом и "исключением в Вашем понимании". Кстати, а где конкретно вы собираетесь их ловить ? softwarer Ошибку в обоих случаях вызывает непредсказуемая внешняя среда - в одном случае, например, админ, который потушил сервер БД, в другом случае тот же админ, который сделал опечатку в конфиг-файле. В чем разница? Итак, где пролегает граница? Вообще, я могу с вами согласиться, что это очень спорная тема, прямо из разряда филосовских. Мое мнение об таких "границах" основывается просто на рекомендациях в литературе. Например Стив Макконнел призывает использовать исключения только для действительно исключительных ситуаций (правда толком не уточняет каких :) ), Э. Троелсон в "C# и платформа .NET" говорит о применении исключений только в непоправимых ситуациях, а когда есть возможность выхода из ситуации при помощи логики приложения - то исключения не нужны. На мой взгляд, пользовательский ввод не попадает под их разряд - это легко решается логикой приложения (у меня верификатором). А обрыв соединения или сбой сервера во-первых наступают действительно (много) реже пользовательских ошибок, да и обрабатывать простой логикой их уже сложнее. Но вообще я согласен, что эти рассуждения скорее исходят из моего зравого смысла, чем из каких-то точных обоснований, так что точно я вам эту границу не проложу :) softwarer Во-вторых, "выводить ругательное окно" - совершенно не функция верификатора. Он в этом некомпетентен. Дело верификатора - высказать претензии, а кто и как их обработает - вопрос вызывающему объекту. Пожалуйста. Пусть посылает сообщение (претензию) тому, кто будет заниматься выводом этого сообщения. softwarer Хм. Знаете, есть такой принцип: "если что-то выглядит как утка, плавает как утка и крякает как утка, то это утка". Так вот: если мне нужно некоторое "сообщение", которое, во-первых, прервет текущую последовательность исполнения программы, во-вторых, доставит информацию не известному заранее "инициатору", проскочив транзитом через тех вызывающих, которые не хотят это сообщение получить - то это "сообщение" называется "исключение", и пытаться использовать в этом месте что-то другое - мягко говоря, нетехнологично. А почему вы так уверены, что оно выглядит, плавает и крякает прямо как утка ? Любой объект, в том числе исключение, обладает набором свойств и ограничений целостности, которые в совокупности дают нечто, что мы рассматриваем как одно логическое целое. Т.е. мы не можем просто так присвоить аттрибут, который не будет согласовываться с абстракцией класса. Если взять за пример .NET, то в классе Exception вы сможете найти такой аттрибут как StackTrace, который определенно не нужен при передаче неверного параметра из файла. Вот у вашей утки уже и вырос волчий хвост. Можно также там найти ненужный в данном случае InnerException и пр., этак ваша утка скоро начнет покрываться шерстью и даже рычать. Зачам вам такой монстр в программе ? softwarer Я согласен с поставленной задачей, но не с решением и предполагаемыми из него выводами. Во-первых, тут нет никакой разницы между assert и exception (надеюсь, Вы в курсе, как реализовано "отключу assert". Ну а во-вторых, верификатор здесь - менее удачное решение, нежели "флаг в бизнес-объекте, включающий или отключающий проверки". Почему менее удачное: 1. Флаг не требует дублирования кода. В частности, не может возникнуть ситуация "в бизнес-объект добавили некоторую проверку, а продублировать ее в верификатор забыли". 2. Флаг можно сделать включенным по умолчанию - и его потребуется явно отключать там, где программист сочтет это безопасным. Наоборот, в Вашей схеме проверки окажутся "по умолчанию отключены", и программист должен будет специально позаботиться - использовать верификатор - для того, чтобы эти проверки включить. т.е. вы хотите заставить программиста в коде переключать этот флаг ? Имхо, перекомпиляция приложения в случае "больше не хочу проверок" - очень неудачная идея. Свой Trace я могу отключить, просто исправив параметр в .config файле сборки. Вам-же придется либо поставлять 2 exe-шника, либо сразу ставить вопрос ребром - работает только с проверками, либо только без них. softwarer Крайне спорное рассуждение, я бы даже сказал, идеологически ложное. По сути Вы говорите следующее: объект должен вести себя по-разному в зависимости от того, кто его вызвал. Это нарушает базовый принцип модульности. Разумеется, подобная постановка задачи возможна, но зависит они никак не от того, идут ли данные из файла или откуда-нибудь еще. Наиболее естественно в такой ситуации сделать два метода, SetValue и SetCorrectedValue, и в каждом месте вызывать тот из них, который соответствует требованиям задачи. Почему-же идеологически ложное ? Вот возьмем довольно простой пример - в свойствах монитора вашего компьютера вы сможете найти такой параметр как Частота обновления экрана. Там-же рядом стоит галка "Скрыть режимы, которые монитор не может использовать" (так как это может привести к неустойчивой работе и даже поломке). Теперь предположим, что у нас имеется метод SetFrequency(int frequency). Его задача предельно простая - установить требуемую частоту. При считывании данных из реестра (или уж откуда они там считываются) данные необходимо проверять на допустимость. Однако если имеется какая-то диагностическая утилита, то она должна иметь возможность поставить любую желаемую частоту. И что-же, вы теперь хотите наградить класс-владелец еще и методом SetCorrectedFrequency(), который будет запрашивать монитор на список допустимых частот ? А даже если и так, то что вы будете делать в случаях, когда возможны разные варианты получения корректной частоты ? Т.е. например в случае получения из реестра какой-нибудь ерунды, возможна как установка дефолтной частоты, так и получения последней выбранной кооректной частоты из текущего профиля компьютера. Не может такие веши решать класс, ответственный за настройку монитора. softwarer Я бы сказал, остальных она касается еще меньше. Автор BusinessObject вполне может, если захочет, вынести это в некий отдельный внутренний класс (не в смысле inner, а в смысле internal), и таким образом отделить "суть бизнес-объекта" от "вспомогательного кода". Он может дать некий дополнительный интерфейс для управления этими проверками, включения-выключения коррекции итп, если это нужно. хм, но стоит только перевести этот класс из internal в равноправные внешние классы, как он начнет крякать прямо как мой верификатор. Но ведь насколько я понимаю, вы обосновываете наличие проверок в самом методе, а не где-то еще в другом месте ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.05.2007, 18:04 |
|
||
|
Assert vs. Exception
|
|||
|---|---|---|---|
|
#18+
heyа почему вы исходите из того, что при выпавшем Assert приложение придется закрыть ? Ничуть не исхожу, напротив, обосновываю, что оно не так. Если у нас "выпал assert", то есть ровно два варианта действий - либо "ловим", либо "не ловим". Вы сказали "нелогично программировать отлов" - вот я и привожу пример ситуации, в которой "программировать отлов вполне логично". Более того, я вполне осознанно толкаю пример, в котором между assert и exception нет практической разницы с точки зрения необходимой обработки, подчеркиваю, что ловить их в этом случае нужно совместно, одним и тем же куском кода. [font size=4]Однако[/font]. Похоже, я должен извиниться перед Вами, поскольку исходил из неверной посылки и думал о Debug.Assert много лучше, чем он заслуживает. Сейчас я добрался до вижуал студии и посмотрел, как он работает на самом деле, и могу только извиниться за то, что я предполагал по этому поводу раньше и говорил исходя из этого. Так, как он реализован в .NET, Assert, безусловно, совсем не то же самое, что и exception. Более того, это сомнительная хрень, которую без доработки недопустимо использовать в боевых программах (пояснение - release версии обязаны быть откомпилированы без этой... фичи). heyМое мнение об таких "границах" основывается просто на рекомендациях в литературе. Например Стив Макконнел призывает использовать исключения только для действительно исключительных ситуаций (правда толком не уточняет каких :) ), ..... Позволю себе прервать Вас. Мое мнение в данном случае выглядит так: если я, будь хоть трижды уверен в правильности некоего решения в некоторой ситуации, не могу назвать его четко видимых, объективных преимуществ, значит, вопрос тонкий, спорный, и категорические правила в этом случае неуместны; найдется близкая ситуация, в которой какая-нибудь деталь сделает лучшим другое решение. А следовательно, граница зыбка. heyЭ. Троелсон в "C# и платформа .NET" говорит о применении исключений только в непоправимых ситуациях, а когда есть возможность выхода из ситуации при помощи логики приложения - то исключения не нужны. Таких ситуаций нет и не может быть никогда. Просто потому, что когда-то не было исключений, а программы как-то жили и как-то с этими непоправимыми ситуациями справлялись :) Понимаете, хотя теория - важнейшая вещь, большой ошибкой является забывать о ее связи с практикой. В нашей науке теория - это обобщение опыта решения практических задач, и никак иначе. Исключения - это в первую и даже в единственную очередь способ более удачно написать следующий типовой фрагмент кода: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. Когда программистам надоело писать такой (не обязательно по форме, но по смыслу) код, тогда и появились software exceptions. heyда и обрабатывать простой логикой их уже сложнее. Но вообще я согласен, что эти рассуждения скорее исходят из моего зравого смысла, чем из каких-то точных обоснований, так что точно я вам эту границу не проложу :) Я, признаться, не очень понимаю, что Вы называете "обрабатывать логикой", но рад, что мы сошлись по вопросу опоры на здравый смысл. heyПожалуйста. Пусть посылает сообщение (претензию) тому, кто будет заниматься выводом этого сообщения. Уже ближе, но важно - не "выводом", а "обработкой". А кто у нас занимается обработкой такой ситуации? Я построил пример, в котором обработкой должен заниматься инициатор - поскольку ситуация "не прочитан конфигурационный файл" является его проблемой. heyА почему вы так уверены, что оно выглядит, плавает и крякает прямо как утка ? Думаю, правильно будет сказать так: он настолько не выглядит как кто-то другой, что небольшие расхождения во внешности с уткой незаметны. heyЕсли взять за пример .NET, то в классе Exception вы сможете найти такой аттрибут как StackTrace, который определенно не нужен при передаче неверного параметра из файла. Если взять за пример те примеры, что Вы приводили чуть раньше, то это атрибут точно так же не нужен при ситуации "не удалось установить соединение с БД". И точно так же не нужен ни в одной ситуации, которую Вы называете "точно нуждающимися в исключении". Я не хочу здесь уходить в глубокое обсуждение, предлагаю ограничиться констатацией факта, что если принять Вашу точку зрения, придется потребовать от Microsoft-а удаления этого атрибута из класса Exception, что в свою очередь вскроет тот факт, что Microsoft совершенно не "по-Вашему" построило свою модель исключений (ведь null pointer exception, или там array index out of range - это у Вас assert-ы, не exception-ы). Таким образом придется считать, что из вас двоих кто-то кардинально не понимает идеологии исключений :) Прошу прощения, продолжу когда приеду домой. Будет замечательно, если Вы дадите мне закончить прежде чем ответите, и ответите одним письмом на оба моих - иначе наша беседа рискует развалиться, уж слишком много моментов мы обсуждаем, если начнутся еще фрагментарные письма, запутаемся. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.05.2007, 19:59 |
|
||
|
|

start [/forum/topic.php?fid=16&msg=34508113&tid=1346065]: |
0ms |
get settings: |
10ms |
get forum list: |
13ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
169ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
61ms |
get tp. blocked users: |
2ms |
| others: | 239ms |
| total: | 507ms |

| 0 / 0 |
