Работает ли у Вас Дизайн по Контракту?[закрыто]

StackOverflow https://stackoverflow.com/questions/26455

  •  09-06-2019
  •  | 
  •  

Вопрос

Используете ли вы Дизайн по контракту профессионально?Это то, что вы должны делать с самого начала проекта, или вы можете переключить передачу и начать включать это в свой жизненный цикл разработки программного обеспечения?Какие плюсы / минусы, по вашему мнению, есть в таком подходе к дизайну?

Я наткнулся на Проектирование по контракту подход в рамках курса магистратуры.В академической среде это казалось довольно полезным приемом.Но в настоящее время я не использую Design by Contract профессионально, и я не знаю других разработчиков, которые его используют.Было бы неплохо услышать о его фактическом использовании от пользователей SO.

Это было полезно?

Решение

Я не могу рекомендовать его достаточно высоко.Это особенно приятно, если у вас есть пакет, который принимает встроенные спецификации контракта документации, например, так:

// @returns null iff x = 0
public foo(int x) {
  ...
}

и превращает их в сгенерированные модульные тесты, вот так:

public test_foo_returns_null_iff_x_equals_0() {
  assertNull foo(0);
}

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

Другие советы

Вы действительно начинаете ценить дизайн по контракту, когда у вас есть интерфейс между приложениями, которые должны взаимодействовать друг с другом.

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

В случае с контрактом вина очевидна.

Удовлетворил ли вызывающий абонент предварительные условия?Если нет, то клиентская команда должна это исправить.

Учитывая действительный запрос, удовлетворил ли получатель условия отправки?Если нет, то команда сервера должна это исправить.

Соблюдали ли обе стороны контракт, но результат оказался неудовлетворительным?Контракта недостаточно, и вопрос нуждается в обострении.

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

Если вы посмотрите на STL, boost, MFC, ATL и многие проекты с открытым исходным кодом, вы увидите, что там очень много утверждений, и это делает дальнейшее продвижение проекта более безопасным.

Проектирование по контракту!Это действительно работает в реальном продукте.

Фрэнк Крюгер пишет:

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

У меня есть два ответа на это:

  1. Null был просто примером.Для square (x) я бы хотел проверить, что квадратный корень из результата равен (приблизительно) значению параметра.Для установщиков я бы хотел проверить, действительно ли значение изменилось.Для атомарных операций я бы хотел проверить, что все операции с компонентами завершились успешно или все завершились неудачей (на самом деле один тест на успех и n тестов на неудачу).Для заводских методов в слабо типизированных языках я хочу проверить, возвращается ли правильный тип объекта.Этот список можно продолжать и продолжать.По сути, все, что может быть протестировано в одной строке кода, является очень хорошим кандидатом для заключения контракта на код в комментарии к прологу.

  2. Я не согласен с тем, что вы не должны тестировать вещи, потому что они генерируют исключения во время выполнения.Во всяком случае, вы следует тестируйте вещи, которые могут генерировать исключения во время выполнения.Мне нравятся исключения во время выполнения, потому что они создают систему быстро терпит неудачу, что помогает в отладке.Но тот null в примере было приведено результирующее значение для некоторых возможных входных данных.Есть аргумент в пользу того, чтобы никогда не возвращаться null, но если вы собираетесь это сделать, вам следует это протестировать.

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

Вместо более выразительных типовых систем я бы обязательно использовал дизайн по контракту для проектов военного уровня.

Для слабо типизированных языков или языков с динамической областью видимости (PHP, JavaScript) функциональные контракты также очень удобны.

Что касается всего остального, я бы отбросил это в сторону и положился на бета-тестеров и модульные тесты.

Gaius:Среда выполнения автоматически генерирует для вас исключение с нулевым указателем, нет никакой пользы в тестировании этого материала в прологе функции.Если вас больше интересует документация, то я бы использовал аннотации, которые можно использовать со статическими анализаторами и т.п. (например, чтобы убедиться, что код не нарушает ваши аннотации).

По-видимому, лучше всего использовать более надежную систему типирования в сочетании с дизайном по контракту.Взгляните на Спецификация# для примера:

Спецификация# языка программирования.Спецификация# является расширением объектно-ориентированного языка C #.Это расширяет систему типов , включая ненулевые типы и проверяемые исключения.Он обеспечивает контракты методов в форме предварительных и постусловий, а также объектных инвариантов.

Как модульное тестирование, так и проектирование по контракту являются ценными подходами к тестированию в моем опыте.

Я пробовал использовать Design by Contract в системе автоматического тестирования, и мой опыт показывает, что это дает гибкость и возможности, которые нелегко получить при модульном тестировании.Например, можно запускать более длинную последовательность и проверять, что время ответа находится в пределах допустимого при каждом выполнении действия.

При просмотре презентаций на InfoQ выясняется, что проектирование по контракту является ценным дополнением к обычным модульным тестам на этапе интеграции компонентов.Например, можно сначала создать макет интерфейса, а затем использовать компонент после- или при выпуске новой версии компонента.

Я не нашел инструментария, охватывающего все мои требования к дизайну для тестирования по контракту на платформе .Net / Microsoft.

На самом деле я не использую Дизайн по контракту, на ежедневной основе.Однако я знаю, что это было включено в D язык, как часть языка.

Да, это так!На самом деле несколько лет назад я разработал небольшой фреймворк для проверки аргументов.Я делал проект SOA, в котором другая серверная система выполняла все виды валидации и проверки.Но чтобы увеличить время отклика (в случаях, когда входные данные были недопустимыми, и уменьшить нагрузку на эти серверные системы), мы начали проверять входные параметры предоставляемых сервисов.Не только для Not Null, но и для строковых шаблонов.Или значения из наборов.А также случаи, когда параметры имели зависимости между собой.

Теперь я понимаю, что в то время мы реализовали небольшой дизайн по контракту framework :)

Вот ссылка для тех, кто заинтересован в небольшом Проверка аргумента Java рамки.Который реализован как простое Java-решение.

Я нахожу это красноречивым, что в языке программирования Go нет конструкций, которые делали бы возможным проектирование по контракту.panic / defer / recover - это не совсем так, поскольку логика defer и recover позволяет игнорировать panic, т.е. игнорировать нарушенный контракт.Что необходимо, по крайней мере, так это какая-то форма необратимой паники, которой на самом деле нет.Или, в лучшем случае, прямая языковая поддержка проектирования с помощью контрактных конструкций (предварительные и последующие условия, инварианты реализации и класса).Но, учитывая решительность языковых пуристов у руля корабля Go, я практически ничего из этого не меняю.

Можно реализовать поведение, подобное assert, проверив наличие специальной ошибки assert в функции last defer в panicking function и вызвав runtime.Breakpoint() для сброса стека во время восстановления.Чтобы быть похожим на assert, такое поведение должно быть условным.Конечно, этот подход рушится, когда добавляется новая функция defer после той, которая выполняет assert.Что произойдет в большом проекте точно в неподходящее время, что приведет к пропущенным ошибкам.

Я хочу сказать, что assert полезен во многих отношениях, что необходимость танцевать вокруг него может стать головной болью.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top