Как вы относитесь к обучению обработки исключений для программистов. Все остальные вещи учат легко - структуры данных, ASP.NET, WinForms, WPF, WCF - вы называете это, все можно легко научить.
С обработкой исключений, обучение их try-catch-finally является просто синтаксической природой обработки исключений.
Однако чему следует учить: какую часть кода вы помещаете в блок try ? Что вы делаете в блоке catch ?
Позвольте мне проиллюстрировать это на примере.
Вы работаете над Windows Forms Project (небольшой утилитой) и разработали его, как показано ниже, с 3 различными проектами.
- UILayer
- BusinessLayer
- DataLayer
Если в DataLayer возникает исключение (скажем, загрузка XDocument вызывает исключение) (UILayer вызывает BusinessLayer, который, в свою очередь, вызывает DataLayer), вы просто делаете следующее
//In DataLayer
try {
XDocument xd_XmlDocument = XDocument.Load("systems.xml");
}
catch(Exception ex)
{
throw ex;
}
который снова добавляется в BusinessLayer и который перехватывается в UILayer, где я записываю его в файл журнала?
Это то, что вы делаете с обработкой исключений?
Ответы:
Чтобы объяснить обработку исключений, объясните концепцию, лежащую в основе этого: код, где часто происходит ошибка, не знает, как правильно обрабатывать эту ошибку. Код, который знает, как правильно его обрабатывать, может быть функцией, которая вызвала его, или может быть дальше по стеку вызовов.
Когда вы пишете подпрограмму, которая вызывает подпрограмму, которая может вызвать исключение, если вы знаете, как правильно обрабатывать эту ошибку, поместите вызов в блок try и поместите код обработки ошибок в блок catch. Если нет, оставьте это в покое и позвольте чему-то выше вас в стеке вызовов обработать ошибку.
Сказать «поймай экс, брось экс» не очень хороший способ обработки исключений, поскольку на самом деле он ничего не обрабатывает. Кроме того, в зависимости от того, как работает модель исключений в вашем языке, это может быть вредно, если она очищает информацию трассировки стека, которую вы могли бы использовать для устранения проблемы. Просто позвольте исключению распространяться вверх по стеку вызовов, пока оно не достигнет подпрограммы, которая знает, как с ним справиться.
источник
Как и большинство вещей, исключения и обработка исключений, вероятно, будут казаться решением для поиска проблемы новым программистам, пока вы не покажете, почему, казалось бы, более простое решение (коды возврата в стиле C и errno) работает так плохо. Я бы начал с мотивации проблемы и ее решения. Покажите, как можно обрабатывать ошибки, используя коды возврата или глобальные / статические переменные. Затем приведите примеры того, почему это не работает. Тогда и только тогда, представьте исключения и объясните, что они являются формой внеполосной сигнализации и что весь смысл в том, что поведение по умолчанию, если вы игнорируете исключение, состоит в том, чтобы передать нагрузку стеку вызовов тому, кто может справиться.
Итог: демонстрация того, как обработка ошибок была сделана в C, поможет студентам понять, для чего действительно нужны исключения и почему перехват исключений, которые вы не можете реально обработать, в основном имитирует то, как все происходило в темные века.
источник
Я бы начал с краткого руководства по проектированию исключений, которое включает в себя DO, NOT и AVOID. Это также дает причины почему.
В вашем примере, раздел revelvent будет Wrapping Исключения
И ожидал, что это будет написано так. Обратите внимание, что он перехватывает конкретное исключение и пытается добавить информацию для распространения более значимого сообщения. Также обратите внимание, что внутреннее исключение все еще сохраняется для целей регистрации
ОБНОВЛЕНИЕ Канини спрашивает, правильно ли иметь этот блок исключений на уровне данных или проверка файла должна быть доступной для бизнес-уровня.
Ну, во-первых, я хотел бы указать, что обоснование исключения из упаковки заключается в следующем
Так что если вы чувствуете, что более высокий уровень должен знать о файле вообще, то ваш уровень данных должен выглядеть следующим образом
Не пытайся, не лови.
Лично я чувствую, что если ваш уровень данных не может сделать что-то полезное, например, использовать стандартный файл systems.xml, который является ресурсом сборки, ничего не делать или переносить исключение - это хорошая ставка, поскольку при ведении журнала вы узнаете, каким методом и каким файлом была проблема. (
throw ex
в этом случае или предпочтительныйthrow
тоже, но не добавляет ценности). Это означает, что после определения вы сможете быстро решить проблему.В качестве примера этот конкретный пример также имеет следующую проблему в том, что XDocument.Load может выдавать четыре исключения
Мы не можем с уверенностью гарантировать, что следующий код не вызовет и FileNotFoundException, просто потому, что он может быть там, когда мы делаем проверку существования, и исчезать, когда мы делаем загрузку. Наличие этого доступного для бизнес-уровня не помогло бы.
SecurityException еще хуже, потому что среди других причин, по которым оно вызывается, если другой процесс захватывает эксклюзивную блокировку файла, вы не получите ошибку, пока не попробуете открыть ее для чтения, потому что нет метода File.CanIOpenThis (). И если такой метод существовал, у вас все еще та же проблема, что и с File.Exists
источник
Давайте сделаем ролевую игру. (это не шутка)
Вы должны провести семинар, где вы разыгрываете цепочку вызовов. Каждый человек - это объект. Вам понадобятся новички и люди, которые понимают, что «игра» помогает.
Используйте действительно простую проблему, такую как файл IO. gui-> модели-> file_io
Человек, являющийся читателем файла, должен сообщить следующему ....
Сначала сделайте это с кодами возврата. (использовать заметки?)
если взаимодействия - это просто «то, что написано в коде», то очень скоро вы можете заставить людей понять, что исключения являются исключительными.
для кодов возврата передайте сообщение об этом.
за исключением, поднимите руки вверх и скажите, в чем проблема.
затем заставьте их выполнить команду «поймать х, выбросить х» и увидеть, что гораздо хуже диагноз - это то, что GUI просто получает: «модель имела исключение»
Я думаю, что это будет работать для обучения ваших людей, потому что люди очень хорошо понимают взаимодействие с другими людьми.
источник
Я хотел бы представить себе, чтобы понять исключения, которые вы должны сначала понять, например, отношения ребенка с родителем классов. Если вы понимаете, что ребенок может наследовать функциональность от родителя, он может на начальном уровне понять, что, если у ребенка есть проблема, с которой он не может справиться, он передаст эту проблему (исключение) своему родителю и разрешит родительской операции с этим.
Это становится цепным отношением, пока вы не получите место, где что-то знает, как обрабатывать исключение.
И что касается, наконец, это тривиальная часть ... когда возникает проблема, что-то должно с ней справиться, чтобы программа не заканчивала работу фатально, после того, как это исключение было обработано, там есть блок finally, который всегда будет выполняться независимо от попытки catch ,
Хороший пример этого может быть с сетью:
или в исключительном случае:
источник
Подайте заявку новичку с очень хорошей обработкой исключений. Создайте какое-нибудь исключение и дайте им отладить его с помощью журналов. Отслеживая распространение исключения, они должны быть в состоянии отладить его. Сделайте это упражнение 3 или 4 раза. Теперь просто удалите всю обработку Exception из кода и позвольте им попытаться отследить одно и то же исключение.
Я верю, что оценка кода обработки исключений будет сразу оценена.
источник
ИМО, вы должны думать, что операторы обработки исключений и управления потоками в основном совпадают. Вы используете их для управления потоком ваших программ в зависимости от того, в каком состоянии они находятся. Разница в том, что обработка исключений будет реагировать только при возникновении ошибки (или исключения).
источник
Возможно, это не поможет новому программисту, но я обнаружил, что понял концепцию исключений намного лучше, когда начал использовать монады в функциональном программировании. Монада вынуждает вас рассматривать каждый «канал», через который данные могут перемещаться в программу или из нее, поскольку все, что она делает, обеспечивает удобную абстракцию, чтобы «скрыть» часть этого потока данных.
Идея о том, что функция может иметь различные типы выходных данных, а исключение похоже на более высокий приоритет возврата из функции, довольно опрятна.
Имейте в виду, я понимаю, что не так, как исключения работают в большинстве языков (детали реализации), но в абстрактном смысле, это то, что происходит.
источник
Притворись, что обезьяна использует клавиатуру
Я обычно говорил моим парням, когда они пишут код, притворяясь, что обезьяна будет сидеть за клавиатурой и использовать это приложение.
Это научило их, как предвидеть все виды вещей:
Я думаю, что слово «обезьяна», которая просто стучала по клавишам и делала все, что ей хотелось, вместо того, чтобы хорошо следовать за этим, добилось цели. Это сработало для меня.
источник