Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Delphi vs Java2
|
|||
|---|---|---|---|
|
#18+
уф..., осилил :) softwarer MemCheck крайне удобен для профилактики ошибок у кастомера раньше, чем они произойдут, хотя в его информацию стоит заглянуть и после того, но вопрос не в этом. Если посмотрите, он был упомянут в контексте возможности получить стек вызовов вне контекста исключения, просто стек для текущего момента - что, как я сейчас нашел, появилось в java только с версии 1.5. А как же new Exception().getStackTrace() в 1.4, или принт стектрейса в всвой стрим с последующей обработкой? :) softwarer Давайте тогда отмотаем чуть назад. Вы назвали throws логичным, поскольку она дает информацию о возможных исключениях. Хорошо. С моей точки зрения, например, абсолютно логичен вызов setModel (null). Почему-то этот логичный вызов вызывает exception, причем не NullPointerException, которого я мог бы ожидать по предыдущему опыту с JTree, но нечто другое. Информации об этом - нет, по крайней мере в throws. Мне все равно надо лезть в исходники и проверять. Давайте говорить не о том, чего нет нигде, а о том, что есть хоть где-то. Или на пальцах: перед вами класс#метод: SomeClass#setBlaBla(int a, int b, int c, int d); (на любом языке, сути не меняет) Вы видите его первый раз в жизни, вопрос: Какие значения можно передать в этот метод и что будет если передать другие значения? Знаете ответ? Может быть для java и delphi он как-то различается? Нет? Ну-ка, ну-ка.... хочу его улышать. Мы с вами уже спорили на эту тему в форуме по java. Ну или покрайней мере пытались :) В дельфи не силён, но, как я пронимаю, все эксепшины там "unchecked" в терминологии java. Разделение же на сhecked/unchecked exceptions - палка о двух концах, т.к. 1. Оно предполагает знание неких "паттернов" (аналогичные знания необходимы для работы с методами clone, equals, hashcode, etc), следование которым приводит к надёжно работающему и устойчивому к случайным сбоям коду. Одна только не обходимость писать этот "дурацкий catch" уже плюс, т.к. вольно не вольно заставляет помнить, что существует что-то ещё кроме успешных сценариев работы приложения :) 2. Не знание паттернов приводит к рождению антипаттернов ( пустой catch, ловля errors, без дальнейшего пробрасывания и т.д.) Но(!), по пути 2 идут те же люди, что игнорируют обработку "кода возврата", считая, что результат выполнения метода всегда успешен, либо отдают обработку ошибок на откуп среде выполнения (компилятору) принимающему решение за них, а поэтому эксепшины не могут принести в код больше вреда, чем их отсутсвие А посему - не надо на них ругаться, их нужно понимать :) Хочу сослаться на книжки: "java без сбоев, обработка ошибок и ёклмн" http://www.ozon.ru/context/detail/id/2342758/, и главу об обработке ошибок у Рихтера в ".NET Framework" http://www.ozon.ru/context/detail/id/2279035/. Мне все равно надо лезть в исходники и проверять. Код сам писаться никогда не будет :) Можно развить тему борьбы с NPE (@Nullable, etc), вполне похвально и разумно пытаться выявить такие вещи в компил тайм. Но есть же ошибки другого типа (элементарный пример метода, где не понятно, что и как передавать я привёл). Тут всё равно придётся изучить библиотеку перед тем как её использовать - грустно, но факт %) Если повезёт, и документация будет полной - отлично, иначе - в код и тестовые запуски. И никуда от этого не убежать - не важно на delphi, java или ином диковинном языке написан код - вины эксепшинов в этом нет. Они только помогают, как могут, справиться с "нелёгкой" программерской участью %) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.11.2005, 18:08 |
|
||
|
Delphi vs Java2
|
|||
|---|---|---|---|
|
#18+
DarkSquidКстати, приведённый выше кусок кода можно и так записать: Согласен, Ваш вариант изящнее. Тем не менее, с моей точки зрения, сама по себе необходимость сказать нечто типа "для всех потомков X, кроме Y, сделать Z" означает неудачную структуру классов. Поскольку означает, что у "всех кроме Y" есть нечто общее, но нет соответствующего общего предка. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.11.2005, 19:46 |
|
||
|
Delphi vs Java2
|
|||
|---|---|---|---|
|
#18+
wessenКак я понимаю вы привели пример из какого то базового класса. Скажите какой именно класс и метод, а мы посмотрим. Если не изменяет память, это swing.tree.TreePath. Метод, извините, не скажу, поскольку не хочется ради этого скачивать jdk :) wessenВсетаки (я тут подумал) выкидывать нужно IllegalArgumentException, если входной параметр(ы) метода не соответствует каким либо требованиям, даже если он null. Согласен. Я - так вообще не могу назвать ни одной ситуации, когда нужно явно в коде возбуждать NullPointerException. imho это в чистом виде исключение java-машины, аналог "аппаратного" исключения. При беглом просмотре классов свинга так оно и есть. По поводу вашего примера, если child это глобальная переменная, то все логично, если это все таки параметр метода, то система ошибок java тут все равно не причем, тут уже нужно ловить индуса, который это написал и выяснять, почему он так сделал. автор С моей точки зрения, например, абсолютно логичен вызов setModel (null) А для меня логично вообще не вызывать метод setModel, если модели как таковой нет. Чем же это логично, если это оставит действовать старую модель? Вообще говоря, это тема для отдельного большого обсуждения, но в практике программирования есть некая тонкая разница между "идеологически правильно" и "удобно". Грубо говоря, хороший продукт должен быть наиболее удобным из всех возможных идеологически правильных. И один из признаков удобного продукта - отсутствие лишних, пусть и формально правильных сообщений об ошибках; гибкость, способность адаптировать свое поведение там, где есть разумный метод для этого. В следующем примере я могу чуть ошибиться - поскольку без исходников - но думаю, проиллюстрирую мысль. В вызовах Код: plaintext и Код: plaintext имхо логически крайне мало разницы, но физически - один из них выдаст exception, другой нет. Лучшее, что я могу сделать в своем классе - это Код: plaintext после чего пользователи моего класса избавятся от необходимости помнить об этой особенности. И имхо такие вещи надо закапывать в библиотеки, чем глубже, тем лучше. Я бы предпочел тоже об этом не помнить, а сосредоточиться на функциональности моего класса. авторРовно так же, как и любая другая ошибка. А какая другая? Если не Runtime, то их не надо устранять, их нужно правильно обрабатывать. Отчего же такое различие? Нужно именно что устранять. Например, "дата начала должна быть меньше даты завершения" - это с Вашей точки зрения бизнес-исключение, которое надо обработать, или же runtime, который надо устранить? Такое чувство, что вас одолели Runtime ошибки, а с не Runtime вы вообще мало знакомы. Например: Не совсем так. Если говорить обо мне, то мне надоело держать в голове кучу малоинтересных технических подробностей и время от времени натыкаться на новые. Если же говорить о моих претензиях к throws, то мне не нравится тот код, который в результате этой директивы создают мои коллеги, да и авторы некоторых стандартных решений тоже. Возможно, эта та же претензия к "идеологически правильно, но практически неудобно". Практически - там, где в дельфе в худшем случае разбираешься, почему вылетело окошко с access violation, в жаве ищешь таинственную ошибку, и в конце концов находишь очередной catch (Exception e) {}. Я уже почти дошел до желания ежедневно обрабатывать исходники регулярным выражением, которое искало бы эту хрень. // устраняем раз и навсегда IllegalArgumentException if(null != userData){ Уже неудобно, кстати. Проверки на null - техническая деталь, которая должна быть закопана в недрах реализации и которой в логике совершенно не место. В остальном - боюсь, не понял Вашего примера. try{ validate(userData); }catch(MyWrongDataException e){ //выводим красивое окошко... } } И, кстати, от таких фрагментов кода я предпочитаю избавляться. Я вообще полагаю, что неленивый программист - страшная опасность для окружающих. У меня аналогичный фрагмент выглядит примерно так: Код: plaintext 1. 2. 3. 4. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.11.2005, 20:30 |
|
||
|
Delphi vs Java2
|
|||
|---|---|---|---|
|
#18+
softwarerЕсли посмотрите, он был упомянут в контексте возможности получить стек вызовов вне контекста исключения, .... А как же new Exception().getStackTrace() в 1.4 Хм. А new Exception() у нас "вне контекста исключения"? Я, кажется, не говорил, что этого нельзя сделать; я привел пример того, что в дельфе это можно сделать без извращений. А в жабе - только с 1.5 или принт стектрейса в всвой стрим с последующей обработкой? Угу. Создал PrintWriter, натравил его на строковый объект, напечатал в него трейс, подключил регулярные выражения, распарсил... Главное - нескучно; чувствуешь, что Делом занимаешься, а не просто-напросто программируешь то, что нужно клиенту, как эти лохи вокруг ;-) Давайте говорить не о том, чего нет нигде, а о том, что есть хоть где-то. Давайте либо начнем новую ветвь обсуждения, либо продолжим старую ветвь в контексте этой старой ветви. (последующее добавление) Я так понял, что мы пошли по первому из этих путей. Какие значения можно передать в этот метод и что будет если передать другие значения? Знаете ответ? Может быть для java и delphi он как-то различается? Нет? Ну-ка, ну-ка.... хочу его улышать. Нет, по большому счету он для java и delphi никак не отличается, по крайней мере с тех пор как в java появились enum-ы. В дельфи не силён, но, как я пронимаю, все эксепшины там "unchecked" в терминологии java. Не знаком с этой терминологией, но скорее всего именно оно и есть. Разделение же на сhecked/unchecked exceptions - палка о двух концах, т.к. 1. Оно предполагает знание неких "паттернов" (аналогичные знания необходимы ...... 2. Не знание паттернов приводит к рождению антипаттернов Не соглашусь с такой трактовкой. Не незнание паттернов, а их то ли выдуманное, то ли действительное неудобство; желание "просто решать простые задачи", "ну ведь здесь же действительно не будет проблем, а иначе требуется городить лишний код" итп. Но так или иначе - я пока что вижу один конец палки: появление вредных, очень неприятных антипаттернов. Вижу другой конец палки: "знаемые паттерны" не всегда удобны. И вижу третий конец палки: тогда, когда эти паттерны удобны, никто не мешает применять их без принуждения компилятором, иначе говоря противовесом вредным антипаттернам является хинт, мелкая помощь. Приведу некую аналогию: в некоторых языках, например в ADA, и в частности в том же Паскале была введена сильная типизация; можно определить например вещественный тип "Килограммы", вещественный тип "Километры", и компилятор не даст просто так складывать их в арифметическом выражении. Хорошо? Для своих задач, бесспорно, да. Теперь давайте предположим, что эта мысль доведена до абсурда, и в каждом классе/модуле/чемугодно нужно писать, что Class1.Килограммы cовместим с Class2.Килограммы, Class3.Килограммы.... Также давайте предположим, что параллельно в язык введен универсальный тип наподобие variant, способный хранить данные любого типа. Что мы сделали? С моей точки зрения - создали для программиста сильное искушение послать всю эту типизацию нахрен и абсолютно везде пользоваться variant-ом. Хорошо? Да нет, полагаю, хреново. Вообще говоря, получается несколько забавная ситуация. Дело в том, что один из больших (с моей точки зрения) плюсов Object Pascal - детальная проработанность языка, максимально осложняющая процесс "хотел написать одно, а получилось другое". Так, стандартный для C++ и java вариант "опечатался в имени переопределяемого виртуального метода либо переименовал метод в предке и не поправил в потомке" там просто невозможен - вернее, его результатом будет ошибка компиляции. Директива throws, вообще говоря, пытается достичь той же цели и вроде бы мне следовало ее ценить. Реально - я в принципе готов оценить правильность идеи, но по опыту использования - неудобно. Порождает больше проблем, чем решает. softwarer Но(!), по пути 2 идут те же люди, что игнорируют обработку "кода возврата", ... Не скажу, что полностью согласен, но во многом. Давайте определим цель, которую мы преследуем, предлагая к реализации ту или иную систему обработки ошибочных ситуаций. С моей точки зрения, коротко она описывается так: уменьшение суммарной стоимости [последствий] реально возникающих проблем. Соответственно, для достижения этого нужно, чтобы реальные программисты (в том числе "те же люди") писали максимально дешевый в смысле возможных последствий код. Скажу сразу, идею заранее научить всех программировать "как надо" я считаю утопической даже в первом приближении. Далее, я полагаю игнорирование ошибки - практикой, порождающей намного более тяжелые последствия, нежели аварийное завершение (падение) программы, а аварийное завершение - практикой, порождающей более тяжелые последствия, нежели модель дельфы по умолчанию (по сути - прерывание текущей операции с выдачей окна с текстом исключения). Игнорирование кода возврата и пустой catch - это именно то самое игнорирование ошибки, и текущая реализация просто подталкивает к этому. Например, actionPerformed не имеет throws - это же просто бред. Да, так гораздо легче было писать awt/swing - ну и получилось на выходе то, что получилось. Сухой остаток состоит из двух пунктов опыта - сравнения "как там" и "как тут". 1. Модель, реализованная в дельфе, принципиально реже приводит к тому, что (работающие со мной и у меня) программисты более-менее эквивалентного уровня пишут код, который я полагаю абсолютно недопустимым. 2. Лично от меня реализация хорошей (с моей точки зрения) обработки ошибок в дельфе требует заметно меньших усилий, нежели в java. Но есть же ошибки другого типа (элементарный пример метода, где не понятно, что и как передавать я привёл). Тут всё равно придётся изучить библиотеку перед тем как её использовать - грустно, но факт %) Боюсь, Вы таки недостаточно полно осилили предыдущее обсуждение. Как ни странно, примерно это я и доказывал своим оппонентам - все равно никуда не денешься. В то время как мне задавались вопросы типа "а вы что - любитель лазить в исходники?" и подобные. Если бы throws и/или еще что-нибудь решали бы эти проблемы - я был бы очень рад. Но ведь не решают - просто приходится писать лишнее. И - то, к чему я отношусь намного хуже - маскировать суть, функциональность, нагромождением технических деталей. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.11.2005, 21:55 |
|
||
|
Delphi vs Java2
|
|||
|---|---|---|---|
|
#18+
Буду краток :) softwarer Как ни странно, примерно это я и доказывал своим оппонентам - все равно никуда не денешься. В то время как мне задавались вопросы типа "а вы что - любитель лазить в исходники?" и подобные. Нет, вы доказывали, что cчитать объявления exception'ов заменой "лазанья по исходникам" нельзя. (Я правильно понял?) Я же, как и sun, говорю, что они предназначены не для этого (затем и отсылал к книжкам). Цель эксепшинов не сигнализация о не корректности аргументов, а оповещение об исключительных, но *ожидаемых* событиях (например, потеря соединения с базой данной). В отличии от кодов возврата, их нельзя проигнорировать "неосознанно" или "от рассеяности". Наследники RuntimeException, Error и (боже упаси) прямые наследники Throwable выполняют уже другую функцию. Это, главным образом, средства диагности проблем для программиста. Понимаю, тут можно приводить примеры библиотек, где "злой дядя" заставляет обрабатывать RuntimeException на ровне с Exception и нарушает "общественный договор" другими способами :) Хочу только сказать, что ничто не мешает "хорошему дяде" рисовать окошко с ошибкой ручками (забавно было бы пытаться это сделать в консольном приложении для линух без иксов :)) и вести логи при помощи того же log4j или стандартного в java с версии 1.4. механизма, избавляя пользователя от не обходимости что-то куда-то зарисовывать. Не далай зла сам и его станет меньше в мире (с) Л.Н.Толстой в вольной обработке :) Если бы throws и/или еще что-нибудь решали бы эти проблемы - я был бы очень рад. Но ведь не решают - просто приходится писать лишнее. И - то, к чему я отношусь намного хуже - маскировать суть, функциональность, нагромождением технических деталей. Скупой платит дважды. Что тут можно ещё сказать? Нанимаешь дешёвую рабочую силу, не хочешь её обучать - трать деньги на решение возникающих проблем в будущем. з.ы. Я понимаю и принимаю ваши аргументы, но выводы (разный у нас опыт, никуда от этого не денешься) делаю другие :) А истина... абсолютной истины не существует, это знают все %) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.11.2005, 11:55 |
|
||
|
Delphi vs Java2
|
|||
|---|---|---|---|
|
#18+
NotGonnaGetUsНет, вы доказывали, что cчитать объявления exception'ов заменой "лазанья по исходникам" нельзя. (Я правильно понял?) Я же, как и sun, говорю, что.... Боюсь, в данной цитате я отвечал только на первую часть Вашего примера, где Вы строили примерно тот же пример, что и я. NotGonnaGetUsЦель эксепшинов не сигнализация о не корректности аргументов, а оповещение об исключительных, но *ожидаемых* событиях Хм. В первую очередь, я не понял, что Вы имели в виду, и чтобы не задавать кучу поясняющих вопросов, попросил бы Вас переформулировать максимально однозначно, в частности выделив: цель exception-ов или директивы throws, оповещение или принуждение, оповещение кого.... NotGonnaGetUsВ отличии от кодов возврата, их нельзя проигнорировать "неосознанно" или "от рассеяности". Да. К сожалению, их слишком неудобно игнорировать "специально" (под игнорированием я здесь имею в виду "доверить их обработку вызывающей функции"). Поясню на примере. Мой пользователь в рамках одного сеанса работы и одного интерфейса работает с несколькими разными серверами (если угодно - с несколькими движками, выполняющими те или иные функции). На уровне базового окна есть метод refresh(), вызываемый по кнопке "обновить данные", ну и соответственно в зависимости от движка - в одном случае грозит SQLException, в другом - допустим, BIBeansException, итп. И тут - я добавляю новый движок, допустим AWXML, со своим AWException. Что происходит? Я должен прописать AWXML в throws refresh-а, прописать его в throws тех методов, которые его вызывают....... неинтересно, очень неинтересно. Да, я могу не выпускать исключение из refresh, выкидывать там красивое окно и вроде бы решить проблему. Назову только один минус такого решения - есть методы, которые используют refresh в своей реализации. То есть, случись что - посреди бизнес-функции вылетит красивое окно, пользователь нажмет OK, и бизнес-функция почапает дальше, считая, что refresh отработал. Хреново... Если я совсем идиот, я добавлю в refresh код возврата - типа отработал или нет. То есть вернусь в технологии на десять лет назад. Ладно, добавление движка в конце концов случается не так часто - у нас пока что было дважды. Но refresh - такой метод, что можно довольно спонтанно захотеть вызывать его из той или иной бизнес-функции; это не столько постановочный вопрос, сколько вопрос удобства, оптимального дизайна функциональности. Захотели? Ну извините, значит садимся и снова прописываем все исключения refresh-а во все места этой бизнес-функции. Получаем полный идиотизм: функция движка A возвращает исключение, относящееся к движку B, потому что оно может быть результатом refresh-а. Да, конечно, если говорить именно о refresh, то в его общности не так уж много смысла; можно плюнуть и откропировать код. Но ведь это относится к любой общей функциональности. А раз так.. раз так берем и пишем Код: plaintext Ну и смысла в этом, соответственно.... я бы предпочел не писать. По сути, требуется просто добавить throws Exception в половину методов проекта; радости от этого никакой, смысла - столько же. Имхо. NotGonnaGetUsХочу только сказать, что ничто не мешает "хорошему дяде" рисовать окошко с ошибкой ручками Ничто. Ничто не мешает хорошему дяде самому написать все, что надо для комфортной работы - библиотеки, компилятор... Но лучше, когда уже сделано. NotGonnaGetUs (забавно было бы пытаться это сделать в консольном приложении для линух без иксов :)) Ровно настолько же забавно, насколько забавно использовать в таком приложении swing :)) Почему swing - потому что эта часть обсуждения пошла с моей фразы про то, что awt/swing выводят свои исключения в консоль. То есть для пользователя это выглядит как "нажал на кнопку - и ничего не произошло" (приложение не падает, работает дальше). NotGonnaGetUsСкупой платит дважды. Что тут можно ещё сказать? Нанимаешь дешёвую рабочую силу, не хочешь её обучать - трать деньги на решение возникающих проблем в будущем. Можно сказать? Можно сказать, что недешевая рабочая сила хорошо напишет и без throws. Для нее это - необходимость писать дополнительные слова и ничего больше. Для дешевой рабочей силы, судя по процитированному, это тоже не подходит. Так зачем же оно нужно? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.11.2005, 18:33 |
|
||
|
Delphi vs Java2
|
|||
|---|---|---|---|
|
#18+
прерву вашу высокоинтеллектуальную беседу NotGonnaGetUsи вести логи при помощи того же log4j или стандартного в java с версии 1.4. механизма , избавляя пользователя от не обходимости что-то куда-то зарисовывать. NotGonnaGetUs - я понимаю, что RTFM, но не подскажете - как это делается? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.11.2005, 10:11 |
|
||
|
Delphi vs Java2
|
|||
|---|---|---|---|
|
#18+
softwarerБоюсь, в данной цитате я отвечал только на первую часть Вашего примера, где Вы строили примерно тот же пример, что и я. Cорри, не понял ответа %) softwarer Хм. В первую очередь, я не понял, что Вы имели в виду, и чтобы не задавать кучу поясняющих вопросов, попросил бы Вас переформулировать максимально однозначно, в частности выделив: цель exception-ов или директивы throws, оповещение или принуждение, оповещение кого.... Хм... Давайте попробуем. Начну из далека. До появления концепции исключений для обработки ошибок и не стандартных ситуаций во всю использовался подход под названием "код возврата", а так же простое "падение программы с созданием coredump" ;) Эти "технологии", очевидно, имеют свои недостатки. А именно: 1. трудночитаемый и усложнённый код из-за неявной НЕОБХОДИМОСТИ через строчку вставлять проверки кодов возврата. 2. коды возврата в виде "простых" типов не несут достаточно информации о "проишествии", возникает не обходимость создания велосипедов ака методов getLastErrorDescription(), возврата каких-то сложных структур и т.п. усложнения, свои в каждом приложении. 3. поскольку не всегда возможно разрешить "особую" ситуацию в месте её возникновения (решение может зависить от контекста в котором вызвается метод, внтури которого возникает эта ситуация), почти каждый метод ОБЯЗАН иметь код возврата(!). Если следовать этому принципу, то согласно п.1. сколько-нибудь сложный код станет вообще не подъёмный, если не следовать - это приведёт к сокрытию причин ошибок. Всё вместе - это умноженный на тысячу случай, когда вместо Строки метод возвращает null. Пойди разбери почему null - толи аргументы не верные, толи сетевой шнур кто-то выдернул... Вобщем жить с этим конечно можно, но только очень аккуратным/педантичным людям :) Исключения упрощают труд программиста. 1. В случае однотипной обработки ошибки: вместо Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 2. Исключения предоставляют УНИФИЦИРОВАННЫЙ механизм доставки инфрмации об исключительных ситуациях. Эта информация влючает в себя место возникновения, причину ошибки и любую другую полезную информацию для человека-отдачика и существенно упрощает исправление ошибок. 3. Исключения поволяют принимать "решение там, где есть вся необходимая для этого информация". Необработанное исключение передётся выше по цепочке вызова пока не будет найдено место, где оно может быть обработано корректно. Это были общие положения. Если перейти к системе исключений в java, то мы увидим что существует три разновидности исключений: - Error extends Throwable - Exception extends Throwable - RuntimeException extends Exception Первый класс включает ОШИБКИ относящиеся к среде исполнения в целом, например, OutOfMemoryError, VirtualMachineError, StackOverflowError, ConfigurationError. Это ошибки, игнорирование которых приводит к НЕПРЕДСКАЗУЕМЫМ последствиям. Как будет работать колеченная VM никто не знает :) Если их ловят, то главным образом затем, чтобы выполнить необходимые завершающие действия и переслать выше по стеку, но никак не для того, чтобы перепрятать в консоль или лог файл (кроме тех редких случаев, когда действительно ясно, что нужно сделать чтобы исправить ситуацию). RuntimeException (unchecked exceptions) - тоже используется для обозначения ОШИБОК, но уже ошибок программых. Их возникновение не нарушает работу среды исполнения. В отличии от NoClassDefFoundError, после NullPointerException работать вполне себе можно :) Однако это ОШИБКА. Толи программист не правильно использует какой-то код (пытается читать поток после закрытия, засунуть null в качестве аргумента метода и т.д.), толи другой программист написал кривой метод, потому что тоже чего-то забыл или не учёл (толи звёзды так сошлись). А вот Exception (checked exceptions) - это уже не ошибка. Это "Особая Ситуация, Которая Требует Обработки". Например, СlassNotFoundException - это вполне ожидаемый результат попытки загрузить класс по имени, IOException - логично, что чтение из потока может прерватся по какой-то причине. Заметьте, их возникновение не является следствием ошибки программиста (в отличии от ClassCastException, рантайм эксепшина который может возникнуть если я вдруг решу, что некий Object это ни что иное как MyBestObject и влеплю в код каст), ошибкой становится их игнорирование программистом (путём вставки пустых catch'eй, неоправдованное прокидывания в родителя (особенно обернув его перед этим в рантаймэкспешин(!)) и т.п.) Если в думаться, то Exception это дополнительное значение возвращаемое методом, и как любое возвращаемое значение оно должно быть объявлено. Именно для этого используется директива throws - объявляет, что одним из возвращаемых значений метода является некий Exception. И всё казалось бы хорошо, но возникает вопрос: а кто будет обрабатывать RuntimeException'ы? Код - это не просто последовательность операторов. Он состоит из, своего рода, узловых точек, отделяющих операции предметной области (или просто осмысленные действия), такие, что ошибка в одной "операции" не должна отменить следующую за ней. Вот в этих точках и следует ловить ОШИБКИ, как минимум для того, что бы занести их в логи и позволить следующим операциям корректно выполниться. Примером может служить операция получения/построения данных и, следующая за ней, операция передачи данных потребителю (пользователь перед экраном монитора, другое приложение, и т.д.) Писать "общие рецепты" дело неблагодарное, но куда деваться... надеюсь я вызился достаточно однозначно :) ... На уровне базового окна есть метод refresh(), вызываемый по кнопке "обновить данные", ну и соответственно в зависимости от движка - в одном случае грозит SQLException, в другом - допустим, BIBeansException, итп. ... В данном случае напрашивается добавление создание класса RefreshFailedException extends Exception и объявление его в методе refresh(). Код вызывающий метод refresh уже сам должен решить, что делать с этой ошибкой. Точнее програмист, который его пришет :) Захотели? Ну извините, значит садимся и снова прописываем все исключения refresh-а во все места этой бизнес-функции. Получаем полный идиотизм: функция движка A возвращает исключение, относящееся к движку B, потому что оно может быть результатом refresh-а. ... Код: plaintext Cогласитесь, разница с RefreshFailedException велика :) На полном серьёзе. На счёт желания проигнорировать обработку исключения переслав его выше по стеку, если на самом деле его можно обработать в точке получения, полностью согласен - это bad practice, который "легко делается". Но влюбом случае такой поступок не хуже, чем окно с сообщением и последующим завершением программы. Для меня. Ничто. Ничто не мешает хорошему дяде самому написать все, что надо для комфортной работы - библиотеки, компилятор... Но лучше, когда уже сделано. Конечно лучше, но использование того что "хуже", вовсе не причина писать таком же уровне :) Почему swing - потому что эта часть обсуждения пошла с моей фразы про то, что awt/swing выводят свои исключения в консоль. То есть для пользователя это выглядит как "нажал на кнопку - и ничего не произошло" (приложение не падает, работает дальше). Вот оно как... Осталось только разобраться в чём причина: в архитектуре Swing или руках разработчика, который не правильно его приготовил :) Хотя согласен, было бы приятно, если бы готовка заключалась в простом подогреве :) Можно сказать? Можно сказать, что недешевая рабочая сила хорошо напишет и без throws. Для нее это - необходимость писать дополнительные слова и ничего больше. Для дешевой рабочей силы, судя по процитированному, это тоже не подходит. Ну, осталось решить вопрос, какая из недешёвых рабочих сил дешевле: та, что умеет без throws или та, что умеет со throws и которой очень тяжело получается без него? %) Но лучше не решать, а посмотреть как оно на практике получится :) Так зачем же оно нужно? Чтобы был мир во всём мире :) Исключения не идеал, но и говорить что в них нет ничего хорошего тоже нельзя. Ситуация, как с использованием наследования в ооп. Вроде бы и просто всё, но нужно много раз подумать прежде, чем делать. Причём думать нужно на этапе проектирования приложения %) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.11.2005, 19:13 |
|
||
|
Delphi vs Java2
|
|||
|---|---|---|---|
|
#18+
а вот еще вопрос, насколько просто в java реализовать раскраску строк/ячеек грида (табличка со скроллом), в зависимости от находящихся в них значений ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2005, 00:58 |
|
||
|
Delphi vs Java2
|
|||
|---|---|---|---|
|
#18+
NotGonnaGetUs 3. поскольку не всегда возможно разрешить "особую" ситуацию в месте её возникновения (решение может зависить от контекста в котором вызвается метод, внтури которого возникает эта ситуация), почти каждый метод ОБЯЗАН иметь код возврата(!). Если следовать этому принципу, то согласно п.1. сколько-нибудь сложный код станет вообще не подъёмный, если не следовать - это приведёт к сокрытию причин ошибок. По-видимому код ядра юникса не относится к сколько-нибудь сложному коду, неподъемен и сокрывает причины ошибок. Собственно код можно посмотреть, скачав исходники БСД. Что-то мне в жаба-мире не встречалоь ничего близкого по стабильности к юниксу. Хотя по теории, конечно, все должно быть наоборот, никто же не спорит. Я общался с несколькими людьми, пытавшимися переписывать реальный код с обработки кодов возврата на ексепшины. Они отмечали тот необъяснимый факт, что несмотря на все их старания и всю эту красивую теорию, количество кода не уменьшается и читаемость соответсвенно тоже не улучшается. Я тоже с этим сталкивался, но они к этому подошли более капитально. Подчеркиваю: в реальных программах, которые специально основательно переписывались. Что касается приведенного примера, то тут кое-кому следует либо сначала подучить матчасть, либо воздерживаться от категорических заявлений по предмету, в котором слабо разбирается. Тот же код может выглядеть, например, примерно так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. А если fooX(y) будет начинаться со строчки: if(y<0) return y; (а мы помним, что в жабе тоже " вместо возврата "-1" кидается FooException "), то код становится еще проще: Код: plaintext 1. 2. 3. 4. И почему это хуже чем Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. По-моему как минимум не хуже. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2005, 03:07 |
|
||
|
Delphi vs Java2
|
|||
|---|---|---|---|
|
#18+
код возврата хуже в концептуальном плане. Функция должна возвращать полезное значение. Но если что-то пошло не так, то возвращятся недолжно ничего. А должно происходить исключение. Но это все в красивой теории, на практике же, все зависит от того уровня, на который программист захочет(и ему позволят обстоятельства) опустится в проработке алгоритмов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2005, 13:42 |
|
||
|
Delphi vs Java2
|
|||
|---|---|---|---|
|
#18+
Ewg_а вот еще вопрос, насколько просто в java реализовать раскраску строк/ячеек грида (табличка со скроллом), в зависимости от находящихся в них значений ? Вроде просто. Пример можно посмотреть в ${JAVA_HOME}/demo/jfc/TableExample/src/TableExample4.java ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2005, 14:11 |
|
||
|
Delphi vs Java2
|
|||
|---|---|---|---|
|
#18+
Ewg_а вот еще вопрос, насколько просто в java реализовать раскраску строк/ячеек грида (табличка со скроллом), в зависимости от находящихся в них значений ? ФОрум по java в другом месте. Задавай такие вопросы там. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2005, 14:50 |
|
||
|
Delphi vs Java2
|
|||
|---|---|---|---|
|
#18+
c127 По-видимому код ядра юникс ... мне в жаба-мире не встречалоь ничего близкого по стабильности к юниксу. Хотя по теории, конечно, все должно быть наоборот, никто же не спорит. Ну и что? Точно также существует прекрасно читаемый код написанный с кучей GOTO. Разве этот факт означает, что с goto проще и легче писать хороший код? Это значит только то, что человек способен учиться на своём и чужом опыте, вырабатывая "паттерны" эффективного поведения. В том числе эвристики как потрогать goto, что бы оно при этом не воняло :) Нужно только задуматься - а сколько же времени на это обучение уходит? Аналогично с кодами возврата. Я чёрным по белому писал выше: NotGonnaGetUs жить с этим[кодами возврата] конечно можно, но только очень аккуратным/педантичным людям Если вы считаете, что код ядра юниха писался дилетантами, способными без напряжения извилин креативить коды возврата и прочии хитросплетения операторов, то я так не думаю. Прежде всего это был высококвалифицированный труд, к тому же труд выполняемый с любовью. Если бы такие программисты могли бы обеспечить все потребности индустрии, то этот разговор просто никогда не возник бы. c128 Я общался с несколькими людьми, пытавшимися переписывать реальный код с обработки кодов возврата на ексепшины. Они отмечали тот необъяснимый факт, что несмотря на все их старания и всю эту красивую теорию, количество кода не уменьшается и читаемость соответсвенно тоже не улучшается. Я тоже с этим сталкивался, но они к этому подошли более капитально. Подчеркиваю: в реальных программах, которые специально основательно переписывались. Архитектура приложения зависит, в том числе, и из методов обработки ошибок. Если код просто "переписывался", то такой результат в полне объясним. Очень странно пытаться применять старые приёмы в работе с новыми технологиями... Кстати, чтобы переписывать работающий код должны быть веские причины... какие были в ваших случаях? :) c129 Что касается приведенного примера, то тут кое-кому следует либо сначала подучить матчасть, либо воздерживаться от категорических заявлений по предмету, в котором слабо разбирается. Тот же код может выглядеть, например, примерно так: Не разобрался c тонкими намёками: кому нужно подучить матчасть? :) c130 Код: plaintext 1. 2. 3. 4. 5. 6. 7. Это называется пример легко читаемого кода? Я хотел написать с начала именно такую конструкцию, но потом подумал, что если я так поступлю, мне скажут, что я спецаильно всё усложняю %) c131 Код: plaintext 1. 2. 3. 4. И почему это хуже чем Код: plaintext 1. 2. 3. 4. 5. 6. 7. По-моему как минимум не хуже. А теперь двайте разберёмся. Почему fooC вернул -1? варианты: - ошибка в методе А - ошибка в методе В - ошибка в методе С - входные данные для метода А не верны (от куда-то же он берёт значение) - входные данные для метода В не верны - входные данные для метода С не верны - произвольная комбинация выше перечисленного... В случае же FooException мы получаем точное место, где произошла ошибка. Глянув на нужную строчку кода мы увидим, что было не так: толи проверка аргументов не прошла, толи какое-то из допущений в коде fooX() оказалось не верно; а главное мы будем знать в каком из этих трёх методов возникло исключение. Собственно вы предложили недостающую иллюстрацию к тезису: NotGonnaGetUs Если следовать этому принципу, то согласно п.1. сколько-нибудь сложный код станет вообще не подъёмный, если не следовать - это приведёт к сокрытию причин ошибок. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2005, 15:45 |
|
||
|
Delphi vs Java2
|
|||
|---|---|---|---|
|
#18+
Ewg_насколько просто в java реализовать раскраску строк/ячеек грида (табличка со скроллом), в зависимости от находящихся в них значений ? В джаве табличка со скроллом как Маркс и Энгельс - не муж и жена, а четыре разных человека :) У меня в частности есть скриншот, где заголовок таблицы разъехался с его колонками. Терпимо просто. Если говорить о простой раскраске - посложнее чем в дельфе, если о сложной - может быть что и попроще. Если говорить о таблицах, в java не так-то просто запихнуть в них данные :) И меня в свое время совершенно убил случай, когда мне потребовалось сделать табличку без скролла, и только от этого в ней исчезли заголовки :) Это, кстати, задокументированное поведение класса. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2005, 16:44 |
|
||
|
Delphi vs Java2
|
|||
|---|---|---|---|
|
#18+
NotGonnaGetUs Хм. Осилил. К сожалению, меня несколько огорчило то, что начав издалека, Вы в итоге ответили совсем не на заданный вопрос, суть которого - в следующей процитированной фразе. NotGonnaGetUsИсключения не идеал, но и говорить что в них нет ничего хорошего тоже нельзя. Хм. Боюсь, что Вы неосознанно применили очень некрасивый подход - приписали мне (или тому, кому отвечали) не высказанную им и объективно идиотскую точку зрения, после чего с большим или меньшим успехом опровергли ее. Думаю, Вы не сумеете отыскать место, где я бы говорил "в исключениях нет ничего хорошего" либо нечто подобное. Как факт - я сделал и использовал подобный механизм примерно в 90-91 годах; если не ошибаюсь, это было до того, как они появились в дельфе и других доступных компиляторах. Я высказал мнение о том, что реализация исключений в джаве далека от идеала, и мне очень интересна логическая цепочка, по которой Вы вывели из этого "в них нет ничего хорошего". ... На уровне базового окна есть метод refresh(), вызываемый по кнопке "обновить данные", ну и соответственно в зависимости от движка - в одном случае грозит SQLException, в другом - допустим, BIBeansException, итп. ... В данном случае напрашивается добавление создание класса RefreshFailedException extends Exception и объявление его в методе refresh(). Угу. И потребуется упаковка в него SQLException, BIBeansException и прочих, которые от RefreshFailedException никак не унаследуешь. Потом, в коде обработки ошибок, потребуется "выпаковать" произошедшее исключение обратно, чтобы обработать его так же, как и "обычный", допустим, SQLException. Для этого потребуется одно из двух - либо та или иная форма switch/instanceof, либо повторно возбудить это исключение, дабы потом "честно" его поймать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2005, 17:01 |
|
||
|
Delphi vs Java2
|
|||
|---|---|---|---|
|
#18+
softwarerУгу. И потребуется упаковка в него SQLException, BIBeansException и прочих, которые от RefreshFailedException никак не унаследуешь. Потом, в коде обработки ошибок, потребуется "выпаковать" произошедшее исключение обратно, чтобы обработать его так же, как и "обычный", допустим, SQLException. Для этого потребуется одно из двух - либо та или иная форма switch/instanceof, либо повторно возбудить это исключение, дабы потом "честно" его поймать. А зачем упаковывать-распаковывать исключения? Разве это не противоречит такому принципу ООП, как инкапсуляция? Вы написали метод рефреш и, в то же время, хотите так сделать, чтобы вызывающие методы знали о деталях реализации рефреша?! Мне кажется, что это не совсем правильное решение. Разве не было бы лучше для всех, если бы метод рефреша работал сам-по себе, выбрасывая только исключеия связанные с рефрешом, но ни в коей мере не связанные с реализацией этого рефреша? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.11.2005, 22:41 |
|
||
|
Delphi vs Java2
|
|||
|---|---|---|---|
|
#18+
NotGonnaGetUs Ну и что? Точно также существует прекрасно читаемый код написанный с кучей GOTO. Разве этот факт означает, что с goto проще и легче писать хороший код? Это означает, что в Ваших высказываниях имеют место противоречия. То Вы обещали непременно либо нечитаемый либо плохо работающий код (" Если следовать этому принципу, то согласно п.1. сколько-нибудь сложный код станет вообще не подъёмный, если не следовать - это приведёт к сокрытию причин ошибок. "), то оказывается что это не страшно, код может быть хорошим и читаемым, просто нужно быть аккуратным: NotGonnaGetUs жить с этим[кодами возврата] конечно можно, но только очень аккуратным/педантичным людям .... Точно также существует прекрасно читаемый код написанный с кучей GOTO А неаккуратных программистов вообще не бывает. Например паскаль это язык созданный для обучения, специально построен таким образом, чтоб приучить людей к аккуратности. В джаве создается впечатление, что можно программировать неаккуратно. Часто это впечатление специально создается и поддерживается искуственно, мелкософт сильн любит кричать об этом со своим бейсиком и вообще. Но это впечатление ошибочное, неаккуратно все равно программировать нельзя. Люди на это покупаются, в результате получается что хорошие программы можно пересчитать по пальцам. Особенно плохо когда на это покупаются при обучении. По этой причине относительное количество хороших программ на С по-моему больше чем на джаве. Домохозяйки за уши к программированию на С не притягиваются. NotGonnaGetUs Если вы считаете, что код ядра юниха писался дилетантами, способными без напряжения извилин креативить коды возврата и прочии хитросплетения операторов, то я так не думаю. Я вроде такого нигде не говорил о дилетантах. А что, у Вас есть примеры хорошего джава-кода (или любого другого), написаного дилетантами? Напряжение извилин нужно при чтении любого кода. Вы привыкли к ексепшинам, Вам кажется что их читать легко, а мне их читать не очень легко. Я привык к кодам возврата, мне с инми разбираться легче. Эксепшины красивая и вроде бы правильная концепция, но на практике почему-то не работает так как ожидалось. Не знаю почему. NotGonnaGetUs Если бы такие программисты могли бы обеспечить все потребности индустрии, то этот разговор просто никогда не возник бы. От плохих программ пользы все равно мало. Лучше иметь мало хороших, чем много плохих. Не все определяется соображениями оптимальности программирования, часто делаются неоправданные действия, есть же еще маркетинг. Например появление C# с точки зрения технологий ИМХО неоправдано, чистый маркетинг. NotGonnaGetUs Архитектура приложения зависит, в том числе, и из методов обработки ошибок. Если код просто "переписывался", то такой результат в полне объясним. Очень странно пытаться применять старые приёмы в работе с новыми технологиями... Я же специально написал, что код переписывался основательно . NotGonnaGetUs Кстати, чтобы переписывать работающий код должны быть веские причины... какие были в ваших случаях? :) Пытались улучшить код, считали что получится короче и понятнее и что станет легче расширять программы. NotGonnaGetUs Не разобрался c тонкими намёками: кому нужно подучить матчасть? :) Это Ваши проблемы. NotGonnaGetUs Почему fooC вернул -1? Не знаю. У Вас он вернул -1 и у меня он вернул -1. Задача была построить код эквивалентный Вашему. Она решена. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2005, 00:38 |
|
||
|
Delphi vs Java2
|
|||
|---|---|---|---|
|
#18+
DarkSquid #2062348 Что-то фигня какая-то... Пост с номером 2062348 можно смело игнорировать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2005, 00:39 |
|
||
|
Delphi vs Java2
|
|||
|---|---|---|---|
|
#18+
c127Эксепшины красивая и вроде бы правильная концепция, но на практике почему-то не работает так как ожидалось. Не знаю почему. Не знаю, как в Java, а вот в Delphi и WatcomSQL замечательно работает. И наоборот - отсутствие в PB исключений (за вычетом работы с EAServer) иногда очень даже напрягает и превращает код в сплошные ветвления, особенно когда в ходе ошибки в любом операторе необходимо выполнить определенную последовательность действий перед выходом из процедуры по ошибке. Простейший пример - сохранение множества DW в пределах одной транзакции: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2005, 00:54 |
|
||
|
Delphi vs Java2
|
|||
|---|---|---|---|
|
#18+
softwarer NotGonnaGetUs Хм. Осилил. К сожалению, меня несколько огорчило то, что начав издалека, Вы в итоге ответили совсем не на заданный вопрос, суть которого - в следующей процитированной фразе. NotGonnaGetUsИсключения не идеал, но и говорить что в них нет ничего хорошего тоже нельзя. Тоже - хм %) Отвечал я на следующее: Хм. В первую очередь, я не понял, что Вы имели в виду, и чтобы не задавать кучу поясняющих вопросов, попросил бы Вас переформулировать максимально однозначно , в частности выделив: цель exception-ов или директивы throws, оповещение или принуждение, оповещение кого.... softwarer Думаю, Вы не сумеете отыскать место, где я бы говорил "в исключениях нет ничего хорошего" либо нечто подобное. Каюсь, слегка заигрался в словах. Весь текст был нацелен только на опровержения вашего утверждения о том, что дериктива Throws бесполезна и только заставляет тратить время впустую. softwarer NGGU В данном случае напрашивается добавление создание класса RefreshFailedException extends Exception и объявление его в методе refresh(). Угу. И потребуется упаковка в него SQLException, BIBeansException и прочих, которые от RefreshFailedException никак не унаследуешь. Нет, не так. SQLException, BIBeansException и т.д. - это просто cause для refreshFailed. Например, Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. softwarerПотом, в коде обработки ошибок, потребуется "выпаковать" произошедшее исключение обратно, чтобы обработать его так же, как и "обычный", допустим, SQLException. Не понял, зачем его нужно "выпаковывать"? Почему нельзя обойтись обработкой в методе refresh или добавлением в класс RefreshFailedException полей с необходимой информацией для обработчика этого исключения? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2005, 14:56 |
|
||
|
Delphi vs Java2
|
|||
|---|---|---|---|
|
#18+
По порядку... c127То Вы обещали непременно либо нечитаемый либо плохо работающий код (" Если следовать этому принципу, то согласно п.1. сколько-нибудь сложный код станет вообще не подъёмный, если не следовать - это приведёт к сокрытию причин ошибок. "), ... Вы сами подтвердили этот тезис своим примером. Ваш код - скрывает причины ошибок. ..., то оказывается что это не страшно, код может быть хорошим и читаемым, просто нужно быть аккуратным: Да, нужно быть аккуратным, нужно тратить массу времени на то, чтобы разрешать сложности перечисленные под пунктами 1-2-3 в посте выше, вместо того, чтобы тратить свою аккуратность на описание собственно логики приложения. Вы приводили в пример код ядра бсд, который вылизан огромным количеством людей, и содержащий оттого чертовски мало ошибок. Конечно, код в котором НЕТ ошибок не страдает от того, что их СКРЫВАЮТ. Однако время затрачиваемое на устранение ошибок в ещё "не вылизаном" продукте существенно уменьшается при использовании технологии исключений, поскольку меньше времени уходит на выявление причин ошибок. А экономия времени, в свою очередь, даёт конкурентное преимущество на рынке, для которого предназначен данный продукт. Ещё раз: если бы программистов не далающих ошибок хватало - не было бы этого обсуждения. Но рынок требует больше рабочик рук: - нехватает "суперпрограммистов", - возникает работа, которой "суперпрограммист" не станет заниматься - ему слишком сильно жмёт череп Как следствие открывается ниша для "так себе программистов" и новые технологии служат для компенсации понижения "общего скила". Пусть это кому-то и не нравится, но в нашем идотском мире решение остаётся за деньгами, поэтому армия формоклпателей будет жить на тех пор, пока их работа приносит реальную прибыль (отчего-то никто не пытается сэкономить кучу денег посадив 125 программистов за ассемблер, чтобы сделать GUI к БД столовой N5). Одним словом, ситуация такова: "мастер якимыч сделал топором матрёшку за день", а "пьяный васька настрогал 100 матрёшек на станке за пол дня". Привсём не уважении к ваське и любви к якимычу, нельзя не признать, что матрёшки ваське делать проще и экономически выгоднее :) c127 NotGonnaGetUs жить с этим[кодами возврата] конечно можно, но только очень аккуратным/педантичным людям .... Точно также существует прекрасно читаемый код написанный с кучей GOTO А неаккуратных программистов вообще не бывает. Угу, вопрос в том, кто на что тратить свою аккуратность и прочии умения. Всё тот же якимыч и васька. c127 В джаве создается впечатление, что можно программировать неаккуратно ... Особенно плохо когда на это покупаются при обучении. По этой причине относительное количество хороших программ на С по-моему больше чем на джаве. Домохозяйки за уши к программированию на С не притягиваются. Это отдельный вопрос, к исключениям отношения не имеющий, но всё равно интересный. Я всеми руками "за", чтобы в программировании было как можно меньше людей без общей подготовки. Знать основы нужно - это бесспорно. Но причём тут домохозяйки и С ?! Всё, что верно при программировании на С, верно и при программировании на ассме, басике, паскале, джаве - только на практике приходится помимо трудностей "алгоритмических" вникать в трудности языка. А кому нужны лишнии трудности? Грузинскому комсомолу? c127 Я вроде такого нигде не говорил о дилетантах. А что, у Вас есть примеры хорошего джава-кода (или любого другого), написаного дилетантами? Вот и я про тоже. Код ядра писали далеко не дилетанты, но есть уйма задач (которые рождает рынок), где можно использовать "уже не дилетантов, но ещё не профи (или уже никогда не профи? :))". c127 Эксепшины красивая и вроде бы правильная концепция, но на практике почему-то не работает так как ожидалось. Не знаю почему. Может быть сила привычки? c127 От плохих программ пользы все равно мало. Лучше иметь мало хороших, чем много плохих. Не все определяется соображениями оптимальности программирования, часто делаются неоправданные действия, есть же еще маркетинг. Например появление C# с точки зрения технологий ИМХО неоправдано, чистый маркетинг. Если звезды зажигают, значит это кому-нибудь нужно? (с)по телевизору было. Маркетинг... У C# есть очень агрессивные стронники, главным образом среди людей, которые достаточно долго писали на С++. Это получается жертвы рекламы? :) c127 NotGonnaGetUs Почему fooC вернул -1? Не знаю. У Вас он вернул -1 и у меня он вернул -1. Задача была построить код эквивалентный Вашему. Она решена. У меня было два *не* эквивалентых примера один с исключениями, другой без. Пример с кодами возврата и в вашем, и в моём варианте одинаково хорошо демонстрирует его не достатки перед кодом с исключениями, для которого вы не привели эквивалентна... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2005, 16:43 |
|
||
|
Delphi vs Java2
|
|||
|---|---|---|---|
|
#18+
DarkSquidА зачем упаковывать-распаковывать исключения? Затем, что иначе вряд ли удастся совместить предложенный метод с возвратом RefreshFailedException и то, что нужно получить в итоге. DarkSquidРазве это не противоречит такому принципу ООП, как инкапсуляция? Вы написали метод рефреш и, в то же время, хотите так сделать, чтобы вызывающие методы знали о деталях реализации рефреша?! Нет, я - не хочу. И, кстати, у refresh нет никаких "деталей реализации", это тривиальнейший брокер. И если бы не throws, не имел бы никаких проблем с реализацией этого нежелания. Так - приходится решать через throws Exception. DarkSquidМне кажется, что это не совсем правильное решение. Разве не было бы лучше для всех, если бы метод рефреша работал сам-по себе, выбрасывая только исключеия связанные с рефрешом, но ни в коей мере не связанные с реализацией этого рефреша? Для всех было бы лучше, если бы метод вообще не выбрасывал никаких исключений. Я в данном случае говорю про все исключения, без искусственного деления на группы. Увы, это недостижимая идиллия. Этот метод может не отработать, причем список причин, по которым он может не отработать - будет пополняться со временем. Следовательно, у меня три выхода: Выбрасывать эти исключения дальше Выбрасывать эти исключения завернутыми в оболочку типа RefreshFailedException (частный вариант - выбрасывать его, теряя оригинальное исключение) Писать их локальную обработку. Последний вариант в данном случае отпадает потому, что ничего умного там не напишешь. Все, что можно было бы написать, должно быть написано в методе refresh соответствующего движка; если уж оттуда что-то выпало, локальные действия никакого эффекта не дадут. Из оставшихся двух imho надо выбирать по ситуации; мне удобнее первый. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2005, 18:53 |
|
||
|
Delphi vs Java2
|
|||
|---|---|---|---|
|
#18+
NotGonnaGetUsВесь текст был нацелен только на опровержения вашего утверждения о том, что дериктива Throws бесполезна и только заставляет тратить время впустую. Так я и прошу отделять директиву throws от остальных деталей исключений в джаве и от концепции исключений вообще. Исключения - замечательная штука. Исключения в джаве - можно выдвинуть какие-то претензии, но в целом даже "исключения вместе с throws" принципиально лучше, чем отсутствие оных. Что касается throws - это некий зачаток контрактного программирования, от которого лично я (пока что) не вижу пользы и вижу некоторые неудобства. Нет, не так. SQLException, BIBeansException и т.д. - это просто cause для refreshFailed. Именно это я и назвал "упаковать". Вся функция RefreshFailedException - транспортная; туннелинг - донести тот же SQLException до того, кто согласится его обработать. Не понял, зачем его нужно "выпаковывать"? Почему нельзя обойтись обработкой в методе refresh или добавлением в класс RefreshFailedException полей с необходимой информацией для обработчика этого исключения? Обработкой на месте - потому что вся обработка на месте, которая может быть сделана, должна быть сделана внутри того, что Вы в своем примере назвали doSqlRefresh(). Если уж этот метод выбрасывает исключение - значит, на месте ничего сделать нельзя. Что касается "полей с необходимой информацией" - возникают сразу два возражения. Первое: это потеря информации. Получается, что метод refresh() начинает предполагать что-то о тех, кто его вызывает, о том, какие поля внешнему обработчику ошибок понадобятся, а какие - нет. Imho это просто принципиально идеологически криво. Это означает следующее: доработанный sql-движок научился возвращать дополнительную информацию, менеджер ошибок умеет ее обработать - а не сходится из-за того, что какой-то плюгавый местечковый refresh() слишком много о себе возомнил. Это нарушает принцип модульности, то, что сейчас называется инкапсуляцией. Второе: это тривиально менее удобно. Одно дело, в обработчике ошибок я пишу: Код: plaintext 1. 2. 3. 4. 5. 6. Другое дело - там же я судорожно начинаю писать код, который в случае SQLException выдернет из него нужные поля (которые могут быть или не быть в зависимости от класса наследника SQLException) и передаст их на обработку в код, который по наличию или отсутствию значений в этих полях начнет гадать о том, каким же именно был класс ошибки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.11.2005, 19:20 |
|
||
|
|

start [/forum/topic.php?fid=16&msg=33368507&tid=1346901]: |
0ms |
get settings: |
7ms |
get forum list: |
13ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
47ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
60ms |
get tp. blocked users: |
1ms |
| others: | 263ms |
| total: | 404ms |

| 0 / 0 |
