Pull to refresh

Comments 14

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

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

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

То есть, я хочу сказать, что нет смысла во всем коде такие конструкции городить — они нужны только в одном месте, да и там это должно бы решаться более красиво.
Обработки локально важна, т.к. смысловой контекст ошибки понятен именно на том уровне, где произошла исключительная ситуация. В моем случае этот контекст фиксируется и исключение выбрасываеся на уровень выше, где существует свой контекст. Эти контексты накапливаются и на самом высоком уровне могут быть использованы не только для просмотра цепочки и логгирования, но и для передачи в соответсвующий сервис обработки, например. Т.е., наоборот, мы ошибки локально не обрабатываем — только центрально.
В нашем случае, когда мы получим исключение на самом высоком уровне в виде «ошибка оплаты покупки», мы будем знать полный путь ошибки с контекстом (местро возникновения и ключевые параметры слоя) на каждом уровне, через который прошло исключение. Что может пригодиться, например, для понимания, какой из уровней был «виноват».
В привиденном примере нету различия на слои, на верхнем уровне будет видно только SYSTEM_ERROR, а не «Ошибка оплаты покупки».
В приведенном примере маппинга ошибок нижнего слоя в верхний нет.

Если уровень, например, процессинга оплаты, просто «оборачивает» ошибку, то он может заменить в InternalException текущий ErrorRef.ОШИБКа на соответствующий ОШИБКе ErrorRef, например на ErrorRef.PAYMENT_ERROR.

Если уровень обрабатывает ошибку, то он генеририрует новое исключение InternalException но уже со своим референсом ErrorRef.PAYMENT_ERROR.
То есть, я хочу сказать, что нет смысла во всем коде такие конструкции городить — они нужны только в одном месте, да и там это должно бы решаться более красиво.

Каким образом можно получить описанную вами цепочку ошибок добавив обработчик только в одном месте?
Я имел в виду подобный обработчик — обработчик подобной разветвленности с анализом причин.

А так на каждом слое должен быть cтандартный

try {
} catch (Layer1Exception 0) {
throw new Layer2Exception(e);
}

Однако, в принципе, можно извернуться и без него — берем стектрейс — названия классов есть, названия методов есть — все что нужно для анализа подробностей. Хотя зачем эти подробности клиенту?
Простите, но ознакомить команду с AOP и внедрить в проект для подобной обработки ошибок, кажется проще и быстрей, чем всей команде «пересесть» на clojure в проекте, который отягощен архитектурными ошибками прошлого «режима» (Что в прочем никак не отрицает того, что с разумным использованием ФП код действительно получается короче. Но просто людей которые бы с одной стороны умело пользовались бы это парадигмой и при этом были бы не склонны к «стремлению к интеллектуальному иллитизму» в достаточном количестве найти очень не просто + они вряд ли согласятся по разным причинам)
Подпишусь под каждым словом. Просто нам повезло начать несколько проектов на clojure с нуля.
Т.к. людей в команде мало, тут не до «иллитизма». В начале на джаве было уютно: богатый фрэймворк, удобные IDE. Но пугал большой объем кода, требующийся иногда для простых вещей. А рефакторинг требовал много усилий.

Clojure позволил нам писать быстрее и короче не за счет синтаксического сахара и фреймворков с xml-ми, а просто за счет смены парадигмы программирования.

Даже тот пример с обработкой ошибок, который я привел, показателен. Для изменения паттерна достаточно изменить макрос. Изменения в коде, его использующем, если и будут, то будут в минимальном количестве. В джаве нам бы пришлось те изменения, которые мы внесли в макрос, применить в каждом коде с этим паттерном вручную.
UFO just landed and posted this here
Скала рассматривалась в первую очередь.
Сам язык понравился. Но с точки зрения новичков (и поэтому очень субъективно) не рискнули его использовать из-за:

— отсутствия в скале хорошой поддержки в ide (netbeans, eclipse);
— может из-за малого опыта, но «ручной» цикл сборки с помощью maven-a/sdb показался неудобным;
— явная типизация (всякие "_: _ => _") делали код в функциональном стиле очень громоздким;
— в самом языке не понравилось наличие большого количества сущностей.
Sign up to leave a comment.

Articles