Проектирование (программирование) по контракту (Code Contracts) – это метод построения архитектуры программного обеспечения, в соответствии с которым для интерфейсов компонентов системы должны быть разработаны условия определяющие допустимые значения и ожидаемое поведение системы. То есть, мы заранее задаем правила для метода и сигнализируем при их нарушении. Данный подход позволяет на порядок повысить качество и надежность кода, в то же время упрощая тестирование и отладку. Давайте более подробно рассмотрим эту идею.

Программирование по контрактам подразумевает написание дополнительных проверочных условий в методах класса. Данные условия должны гарантировать корректность входных и возвращаемых данных. То есть, данная идея состоит в том, что перед использованием входных данных внутри метода необходимо проверить, удовлетворяют ли они минимальным условиям корректности, а также удостовериться, что после выполнения работы мы получили корректный результат.

Еще одним преимуществом использования данного метода программирования можно считать документируемость кода. За счет декларации в методе требований становится более понятной логика его работы. Кроме того, существуют специализированные утилиты, позволяющие автоматически создавать документацию по коду или создавать модульные тесты. Это не только экономит время разработчику, но и в целом улучшает стиль программирования.

Выделяют три вида условий:

  • Предусловия (Preconditions) – условия корректности входных аргументов метода;
  • Постусловия (Postconditions) – условия корректности результата работы метода;
  • Инварианты (Invariants) – условия корректности переменных метода на протяжении всего его выполнения.

В .NET версии 4.0 и старше для реализации данного метода программирования используется пространство имен System.Diagnostics.Contracts. Давайте рассмотрим, как ей можно воспользоваться.

Для начала нам необходимо создать символ CONTRACTS_FULL или скачать специальную утилиту расширение для Visual Studio. Для того чтобы использовать первый вариант нам достаточно добавить директиву в начале каждого файла, в котором будут использоваться контракты.

Рассмотрим элементарную модель клиента магазина. Создадим интерфейс, в котором будет информация о имени и деньгах клиента, а также предоставим возможность покупать товары.

Предусловия (Preconditions)

Предусловия задаются с в начале метода в следующем формате:

Здесь мы говорим, что переменная productName не должны быть равна null, пустой или состоять из одних пробелов. В противном случае мы генерируем исключение ArgumentNullException с сообщением об ошибке указанном в параметре.

Постусловия (Postconditions)

Постусловия тоже задаются в начале метода.

Здесь мы получаем результат выполнения метода с помощью команды Contract.Result<T>() и говорим что этот результат не может быть равным null или пустым.

Инварианты (Invariants)

Инварианты тоже задаются в начале метода.

Здесь мы говорим, что значение переменной Money должно быть больше либо равно нулю на всем протяжении выполнения метода.

Интерфейсы

Важной особенностью использования данной библиотеки является то, что мы можем создавать контракты для интерфейсов. Тогда все классы реализующие данный интерфейс будут обязаны соблюдать эти контракты. Давайте рассмотрим пример кода.

Теперь создадим класс, в котором опишем все необходимые условия с помощью контрактов.

Теперь создадим класс реализующий данный интерфейс.

Ну и теперь нам остается только вызвать наш код в основном методе программы.

Исходный код можно также посмотреть в репозитории github.

 

 

 
×
%d такие блоггеры, как: