Надежная структура кода?
-
20-09-2019 - |
Вопрос
Я ненавижу писать код, который делает мое программное обеспечение более надежным.Это то, что должен был сделать фреймворк!Итак, знает ли кто-нибудь об утилите «улучшения» кода, которая укрепляет код?
Если бы мне пришлось создать что-то подобное самому, это работало бы следующим образом:Когда вы компилируете свой код с флагом отладки, он автоматически волшебным образом добавляет «затвердевающий» код для каждого метода:
Искажьте код с помощью try-catch и поместите Debug.Assert(true) в catch (чтобы исключения перехватывались в их источнике).
Регистрируйте запись каждого метода, печатая значения аргументов «ToString()», чтобы я мог отслеживать, что происходит.
Проверьте каждый аргумент на ноль.
Используйте структуру «IsValid» для проверки самого объекта и каждого аргумента, где IsValid() — это способ объекта объявить, что его ожидания верны (например, если я TableOfContentsEntry, я ожидаю, что всегда буду находиться в книге, которая IsValid () и указать на страницу, которая является IsValid().
Так почему бы не?
Решение
Если вы хотите регистрировать вызовы методов, вы можете использовать структуру АОП, например ПостШарп.Такие вещи, как обеспечение соблюдения предварительных и постусловий метода, лучше всего достигаются с помощью механизмов проектирования по контракту, таких как новый Кодовые контракты библиотека, которая будет поставляться с .net4.0.Конечно, нет смысла просто проверять аргументы на ноль, поскольку это может быть допустимым значением в зависимости от метода.Внедрение Debug.Asserts в код может быть проблематичным, поскольку вы можете не захотеть/не иметь возможности обрабатывать исключения в исходной функции.Я думаю, что было бы непрактично, если не невозможно, создать общую структуру для такого рода вещей, поскольку требования в разных проектах будут сильно различаться.
РЕДАКТИРОВАТЬ:Чтобы прояснить мой комментарий о добавлении утверждений отладки в методы, я прочитал ваше предложение преобразовать тело метода во что-то вроде этого:
public void SomeMethod(args)
{
try
{
//original method body
}
catch(Exception ex)
{
Debug.Assert(false);
throw;
}
}
Проблема в том, что Asserts указывают на вещи, которые никогда не должны быть ложными, поэтому эта конструкция означает, что метод никогда не может выдавать исключение, что в целом неверно.Проблема теперь в том, что если метод выдает исключение, утверждение завершится неудачно, даже если вызывающий метод соответствующим образом обработает исключение.Судя по вашему комментарию, вы делаете что-то вроде этого:
public void SomeMethod(object arg)
{
Debug.Assert(arg != null);
if(arg == null) throw new ArgumentNullException("arg");
//rest of method
}
Это полезная практика, и я считаю, что библиотека контрактов кода поддерживает «устаревшую» проверку предварительных условий (генерацию исключений) в статическом анализе.
Другие советы
Приятно видеть, что мою книгу затыкают!Большая проблема для меня заключается в том, что я считаю, что генерация кода должна быть «рядом» с кодом разработчика, т.е.в идеале сгенерированный код не должен смешиваться с кодом разработчика.Интересно, есть ли какой-нибудь способ добавить этот «укрепляющий» код как частичный класс или как прокси, который будет установлен между классом и вызывающим его клиентом?Конечно, можно сгенерировать код и вставить его в код разработчика, но вам нужно создать какое-то соглашение, чтобы, когда разработчик вносит изменения и повторно генерирует «продающий» код, инструмент мог удалить старый код и генерировать новый код на основе последней версии кода разработчика.
Мне бы хотелось чего-то, что не теряет ваш стек, когда вы передаете что-то рабочему потоку.Я даже не знаю обходного пути для этого (С#).Было бы здорово узнать стек родительского потока до момента создания рабочего потока.
В общем, я думаю, что многие действительно полезные вещи должны быть встроены в язык, и их невозможно реализовать с помощью одной лишь библиотеки или фреймворка.Я помню, в старшей школе учили всегда писать условия до/после в комментариях к функции, но мне бы очень хотелось увидеть написание условий до/после, которые проверяются, если возможно, во время компиляции, а если нет, то во время компиляции. время выполнения.Они будут помечены каким-то образом, чтобы редактор мог при желании показать или скрыть их, чтобы они не мешали чтению реального кода.
Я сомневаюсь, что что-то подобное существует, а если и есть, то уж точно бесполезно.Это зависит от ваших определений правил, разные люди думают по-разному, имеют разные потребности и рамки...То, что вы описали, может быть достигнуто с помощью метапрограммирования или какой-либо макросистемы.В Java есть несколько проектов, которые могут помочь реализовать такой подход, используя аннотации, не знаю, есть ли какой-то эквивалент во вселенной C#.Однако функциональность isValid() во многом похожа на идею проектирования по контракту, возможно, для этого существуют какие-то рамки.