Надежная структура кода? - PullRequest
       15

Надежная структура кода?

0 голосов
/ 13 января 2010

Я ненавижу писать код, который делает мое программное обеспечение более надежным. Это то, что должна была сделать структура! Итак, кто-нибудь знает об утилите «улучшения» кода, которая укрепляет код?

Если бы мне нужно было создать что-то подобное самому, это работало бы следующим образом: когда вы компилируете свой код с флагом Debug, он автоматически добавит «затвердевающий» код для каждого метода:

Деформируйте код с помощью try-catch и поместите Debug.Assert (true) в catch (чтобы исключения были перехвачены в их источнике).

Регистрируйте запись каждого метода, печатая значения аргументов «ToString ()», чтобы я мог отслеживать происходящее.

Проверьте каждый аргумент на ноль.

Используйте платформу IsValid для проверки самого объекта и каждого аргумента, где IsValid () - это способ объявления объекта, что его ожидания верны (например, если я TableOfContentsEntry, я ожидаю, что он всегда будет Запишите IsValid () и укажите на страницу IsValid ().

Так почему бы и нет?

Ответы [ 4 ]

1 голос
/ 19 января 2010

Если вы хотите регистрировать вызовы методов, вы можете использовать AOP Framework, например PostSharp . Такие вещи, как принудительное выполнение предварительных / постусловий метода, лучше всего достигаются с помощью механизмов разработки по контракту, таких как новая библиотека Code Contracts , которая будет поставляться с .net4.0. Конечно, не имеет смысла просто проверять аргументы на null, поскольку это может быть допустимым значением в зависимости от метода. Внедрение Debug.Asserts в код может быть проблематичным, поскольку вы можете не захотеть / не иметь возможности обрабатывать исключения в исходной функции. Я думаю, что было бы непрактично, если не невозможно, создать общую структуру для такого рода вещей, поскольку требования будут сильно отличаться между проектами.

РЕДАКТИРОВАТЬ: Чтобы уточнить мой комментарий о добавлении отладочных утверждений в методы - я прочитал ваше предложение преобразовать тело метода во что-то вроде этого:

public void SomeMethod(args)
{
    try
    {
        //original method body
    }
    catch(Exception ex)
    {
        Debug.Assert(false);
        throw;
    }
}

Проблема в том, что утверждения указывают на вещи, которые никогда не должны быть ложными - поэтому эта конструкция означает, что метод никогда не может выдавать, что в общем случае неверно. Теперь проблема в том, что если метод действительно выбрасывает, утверждение не будет выполнено, даже если вызывающий метод обрабатывает исключение соответствующим образом. Из вашего комментария кажется, что вы делаете что-то вроде этого:

public void SomeMethod(object arg)
{
    Debug.Assert(arg != null);
    if(arg == null) throw new ArgumentNullException("arg");

    //rest of method
}

Это полезная практика, и я считаю, что библиотека контрактов кода поддерживает «унаследованную» проверку предварительных условий (генерирование исключений) в своем статическом анализе.

1 голос
/ 19 января 2010

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

1 голос
/ 19 января 2010

Мне бы хотелось, чтобы что-то не потеряло ваш стек, когда вы передаете что-то рабочему потоку. Я даже не знаю обходного пути для этого (C #). Было бы здорово узнать стек родительского потока до того момента, когда был создан рабочий поток.

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

0 голосов
/ 14 января 2010

Я сомневаюсь, что есть что-то подобное, и если, то, конечно, это не так удобно. Это зависит от ваших правил определения, разные люди думают по-разному, имеют разные потребности и структуры ... Вещи, которые вы описали, могут быть достигнуты с помощью метапрограммирования или некоторой макросистемы. В Java есть некоторые проекты, которые могли бы помочь реализовать такой подход, использующий аннотации, не знаю, есть ли какой-нибудь эквивалент во вселенной C #. Функциональность isValid (), тем не менее, очень похожа на дизайн в соответствии с идеей контракта, может быть, для этого есть некоторые рамки.

...