Честно говоря, не хотел вас обидеть словами «правильно» и «не правильно». В первой редакции даже написал (там где о шаге) «в описываемой вами» — то есть отдавал должное факту наличия автотестов.
Если не так все радужно, то здесь выход толко локализация шагов рефакторинга. И рефакторинг заменой кода на оттестированый. Сам мучуюсь.
30%: из-за них я месяц назад не стал рисковать. У меня было 2 и 3 дня. Мне показалась что это цифры одного порядка. Хотя конечно каждая система уникальна.
Но цикл с try catch внутри и обработка реальных данных — это не совсем одно и тоже. Повторюсь, факт просадки производительности может подтвердить только profiler. Только он может сказать что данный фрагмент выполняется достаточно часто, чтобы стать причиной проблем в работе системы вцелом.
Например, внутри цикла шифрования я бы этого делать не стал, а для извещения о браке в ключе вполне.
30% это не так много. В любом случае факт просадки производительности из за Exception-ов должен определять profiler.
Сваливание тестов во время рефакторинга, говорит о большой величине шага в процессе его осуществления. На достаточно хорошо покрытой тестами системе правильней откатиться и уменьшить шаг.
А после: недостаточность набора тестов, по крайней мере проверяющих эти аспекты работы. Для теста не особо важно возвращает тестируемая логика null, ResWork.Fail или поднимает Exception — если существует проверка одного, то тест плавно превратится в другое.
Где-то код анализа проблеммы находиться обязан. Но это место не обязано распологаться непосредственно под вызовом критического кода. Это приводит к размытию основоной идеи кода.
Что делает if(-1==reader.ReadByte()) — он пытается интерпритировать ответ. Зачем интерпретировать если можно получить точный, структурированный, расширяемый результат от первого лица?
В то же время ветка if, отвечающая за обработку нестандартных ситуаций в большинстве случаев заканчивается return null-Value (или аналогично — например break). Тем самым мы делегируем ответственность принятия решения о дальнейших действиях.
Оба механизма уже реаизованы: тип исключения точно описывает проблему, а просачивание позволяет определить место где действительно достаточо данных о принятии однозначного решения.
И что это меняет.
Мы насколько я помню говорим о восстановлении состояния (и как частности: освобождение блокировок). А не о бескрайних полях синтаксического сахара C# и проверки результатов инициализации состояния.
По поводу двух строк: я лишь предложил крайний случай закона Мерфи в минимальной реализации. Вы внимательно не анализировали их, а поняли меньше чем за секунду. Следовательно, цели с которой они написаны, достигнуты.
Если же throw new… заменить на вызов «сторонних библиотек» как вы по сути предлагаете, то защищаемый мной подход даст гораздо больше гарантии не потерять стабильное состояние системы.
С помощью if можно проверить результат на null-value, а предполагая возможность exception-ов можно реализовать откат работы, если точно не сказано что все OK — паттерн транзакция (http://insidecpp.ru/patterns/transaction/).
using(new FileInfo("1.txt").OpenText())
throw new MyException();
Я гарантировано освобождаю блокировку файла. Если нет — язык в топку.
Восстановление же фрагментов состояния в разных местах, на мой взгляд, разновидность запаха стрельба дробью (термин по Фаулеру).
Для гарантированного освобождения ресурсов существуют специальные языковые конструкции: finaly, using. Возврат к стабильному состояния с их помощью внушает куда больше доверия, чем операции по else. А потом, если мы говорим об высвобождении ресурсов, их необходимо использовать в любом случае — ThreadAbortException или OutOfMemoryException ни кто не отменял. Если же писать и там и там — получим дублирование.
Изначально рефакторинг писался как перекрытие спины: если что — всегда можно перейти к коду без исключений. 11 пунктов писал с большой не охотой — потому что сам только мельком бы просмотрел. Мой основной аргумент: примеры для рефакторингов не полные и громоздкие. Но вы второй задавший этот вопрос (первый online), а потому сомнения исчезли — пример написан. Как только пойму, как не выводя статью из обсуждения ее исправить, так сразу.
Если не так все радужно, то здесь выход толко локализация шагов рефакторинга. И рефакторинг заменой кода на оттестированый. Сам мучуюсь.
30%: из-за них я месяц назад не стал рисковать. У меня было 2 и 3 дня. Мне показалась что это цифры одного порядка. Хотя конечно каждая система уникальна.
Но цикл с try catch внутри и обработка реальных данных — это не совсем одно и тоже. Повторюсь, факт просадки производительности может подтвердить только profiler. Только он может сказать что данный фрагмент выполняется достаточно часто, чтобы стать причиной проблем в работе системы вцелом.
Например, внутри цикла шифрования я бы этого делать не стал, а для извещения о браке в ключе вполне.
Сваливание тестов во время рефакторинга, говорит о большой величине шага в процессе его осуществления. На достаточно хорошо покрытой тестами системе правильней откатиться и уменьшить шаг.
А после: недостаточность набора тестов, по крайней мере проверяющих эти аспекты работы. Для теста не особо важно возвращает тестируемая логика null, ResWork.Fail или поднимает Exception — если существует проверка одного, то тест плавно превратится в другое.
Мы же об автотестах?
Что делает if(-1==reader.ReadByte()) — он пытается интерпритировать ответ. Зачем интерпретировать если можно получить точный, структурированный, расширяемый результат от первого лица?
В то же время ветка if, отвечающая за обработку нестандартных ситуаций в большинстве случаев заканчивается return null-Value (или аналогично — например break). Тем самым мы делегируем ответственность принятия решения о дальнейших действиях.
Оба механизма уже реаизованы: тип исключения точно описывает проблему, а просачивание позволяет определить место где действительно достаточо данных о принятии однозначного решения.
И что это меняет.
Мы насколько я помню говорим о восстановлении состояния (и как частности: освобождение блокировок). А не о бескрайних полях синтаксического сахара C# и проверки результатов инициализации состояния.
По поводу двух строк: я лишь предложил крайний случай закона Мерфи в минимальной реализации. Вы внимательно не анализировали их, а поняли меньше чем за секунду. Следовательно, цели с которой они написаны, достигнуты.
Если же throw new… заменить на вызов «сторонних библиотек» как вы по сути предлагаете, то защищаемый мной подход даст гораздо больше гарантии не потерять стабильное состояние системы.
С помощью if можно проверить результат на null-value, а предполагая возможность exception-ов можно реализовать откат работы, если точно не сказано что все OK — паттерн транзакция (http://insidecpp.ru/patterns/transaction/).
Если я пишу:
using(new FileInfo("1.txt").OpenText())
throw new MyException();
Я гарантировано освобождаю блокировку файла. Если нет — язык в топку.
Восстановление же фрагментов состояния в разных местах, на мой взгляд, разновидность запаха стрельба дробью (термин по Фаулеру).