Pull to refresh
40
0
Друг @kk86

Пользователь

Send message
Хотя про большие угрозы со стороны изменяемых типов-значений я наслышан, было интересно посмотреть ещё несколько примеров, где могут всплыть проблемы. Спасибо!
Рад, что Вы так восприняли критику. Уверен, Вы неспроста пришли к такой методике, а на то были свои причины. Если решитесь применять подход, буду рад ознакомиться с плюсами и минусами этой практики из жизни. И да, спасибо за статью, «разрыв шаблона» понравился.
Я услышал Вас. Но как-то больше доверяю классическому подходу, когда исключение привычно описывает ситуацию, а клиент метода обрабатывает его. Проще поддерживать, проще понимать.
То, что метод catchException инкапсулирует «что нужно сделать» я понял. Я говорю, что сам класс исключения в такой ситуации выполняет две обязанности, что не очень хорошо.
Кстати, такое применение исключений опасно ещё по одной причине. Очень непривычно их использование. Насколько вероятно, что новый разработчик в команде будет и использовать и реализовывать исключения как надо? Мне кажется, новичок легко и непринуждённо, без задней мысли напишет try-catch в обычном стиле.
Честно говоря, я к исключениям отношусь довольно просто. Исключение это просто ситуация, которую сам метод, возбудающий исключение, не обрабатывает сам, т.к. он не знает как, да и вообще это не его ответственность. Ответственность за обработку ложится на пользователя метода, т.к. «ему виднее». Учитывая это, можно ещё раз рассмотреть вложенные методы с исключениями. Получается, что каждый метод снимает с себя ответственность за одни ситуации и передаёт обработку наверх, там в обработке могут возникнуть свои проблемы. Я считаю, это абсолютно нормально.

Намного более насторожил меня такой код, в котором блоки try вставляются в catch-блоки по нескольку раз. Тут уже стоит задуматься о дизайне.

Что касается простых классов исключений, вида class MyException: Exception {}, то это тоже хорошо. Наследование классов исключений — занятие чреватое. В мире .NET об угрозах такого кодирования написано в «CLR via C#». В общем, широкий набор классов исключений это хорошо. Главная причина в том, что catch (MyConcreteException ex) будет известно что обрабатывать. А в случае наличия наследников, всё будет сильно сложнее. Например, может потребоваться писать мерзкие проверки вида if (ex is MyConcreteSpecificException)
> К сожелению «выделение метода» catch-тел не уменьшает количества catch-блоков.

Ну, тут вариантов два. Либо несколько try-catch блоков, разбросанных по «вложенным методам» это норма для конкретного решения. Либо присутствует какая-то ошибка проектирования. Сами по себе многие try-catch блоки, разбросанные по методам это абсолютно не проблема, если эти блоки необходимы для корректной, ожидаемой, предсказуемой работы метода. Это, кстати, идея не моя, взята из «clean code».

А мне, кстати, понравилась нестандартность решения, описанного в статье.
1. Про «исключение != ошибка» и я с вами обоими. :)
2. А вот три вложенных try-catch намекают на потребность в вынесении методов в большинстве случаев.
Опечатался. «Cather» читать как «catcher».
Мне кажется, что те исключения, которые Вы описали, нарушают принцип единственной ответственности (SRP из SOLID): помимо описания типа исключительной ситуации, факта её возникновения, условий (innerException + data) и места (stack trace), такой класс ещё инкапсулирует и логику обработки такой ситуации. Чуть лучше было бы, если тип исключения ссылался на объект типа «обработчик соответствующего исключения», но это приводит к своим неудобствам (к целому ряду). В общем, не изящно.

Кстати, слово «cather» («перехватчик») довольно неточно. Вы скорее говорите о «handler'е» («обработчике»).
В книге Code Complete таблицы называются Direct Access Tables (18.2.) и Indexed Access Tables (18.3.) Общим названием для них Стив использует lookup-tables. Наверное название «табличный метод» растёт оттуда.
Имхо, кроме силы воли ничто не поможет, т.к. а) редирект можно отменить, если приспичит; б) наверняка найдётся какой-то очередной ресурс, на который человек будет постоянно лезть.
Неясно было назначение. Теперь понял, что strcmp() предназначен для скорее сортировки, чем для сравнения.
Я с Вами полностью согласен, это было не профессионально. Действительно стыдно за Г-код. Видимо, я не умею искать информацию…

Например, гугл-запрос «strings equality php» первыми двумя ссылками даёт отличнейший PHP мануал. И вот на какую из двух страниц ориентироваться?

php.net/manual/en/language.operators.comparison.php
php.net/manual/en/function.strcmp.php
Да, может не очень красиво. Но, а) товарищу может быть стимулом к изучению, как было сказано «основ»; б) товарища я совсем не спалил.
Вы знаете, иногда приходится Г-кодить. Я, вообще, дотнетчик. Довольно неплохой. Но приходится поддерживать часть проекта, писанную на PHP. Сегодня потребовалось сравнить значение двух строковых переменных на равенство. Вспомнил, что в PHP есть не только == и ===, но и strcmp() (и другие), решил поискать в интернетах, как же правильно… В конце концов, обратился к более опытному коллеге, который реализовывает ряд проектов на PHP с этим вопросом. Ответ был: «я всегда использую == и не парюсь, там какие-то различия есть, но я не сталкивался.»

Так это я к чему. К тому что порой бывает, что нет времени разобраться «как правильно», а надо сделать, «чтобы работало». И нет эксперта «под рукой», чтобы дал ответ и объяснил «почему так». В случае с PHP (в отличие от Java, например) мне часто не удаётся сходу найти решение и я делаю в стиле C#… Г-код? Наверняка, а что делать? Сам я предпочитаю изучать языки по книгам, но пока для PHP нет места в ближайшей очереди. К сожалению.

Прошу ни в коем случае не считать моё мнение призывом к холивару. Есть вещи, связанные с PHP, которые мне нравятся. Например, Drupal :)
Shame on me. Ну не читал я про это пока… (
Ок, но я не утверждал, что таски являются потоками. Просто думал, что за Тасками скрываются потоки. Как иначе обеспечить параллелизм я, к сожалению, не знаю.
Пример у меня так и не скомпилится, т.к. публичный конструктор по умолчанию отсутствует у WriteableBitmap. Ссылку на нужную сборку + нэймспейс я как-то разобрался сам вставить.

> Числа будут разные от раза к разу.

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

> Без Sleep получите OutOfMemory при определенном Sleep в зависимости от вашей машины пример начнет полностью работать.

Почему это? Если памяти не будет хватать, будет вызван Collect. В Вашем примере ссылки на созданные объекты нигде не сохраняются, так что они будут засчитаны как недостижимые. Их finalizer'ы будут благополучно исполнены. OutOfMemoryException возникать нет причин, имхо.
Я не буду придираться к тому, что пример не компилируется, а я не силён в Windows.Presentation, чтобы сходу исправить его. Скажите, пожалуйста, что я должен увидеть? И на что именно влияет Thread.Sleep() в этом примере.
Если же Вы имели в виду, что некорректно полагаться исключительно на деструктор, то я согласен с этим. Там где можно следует использовать using или вызов Dispose руками.

Information

Rating
Does not participate
Location
Seattle, Washington, США
Registered
Activity