Проектирование по договору
Проектирование по контракту ( DbC ), также известное как контрактное программирование , программирование по контракту и программирование по контракту , — это подход к проектированию программного обеспечения .
обеспечения определять формальные , точные и проверяемые спецификации интерфейса для программных компонентов , которые расширяют обычное определение абстрактных типов данных предусловиями Он предписывает разработчикам программного , постусловиями и инвариантами . Эти спецификации называются «контрактами» в соответствии с концептуальной метафорой условий и обязательств деловых контрактов.
Подход DbC предполагает, что все клиентские компоненты , которые вызывают операцию на серверном компоненте, будут соответствовать предварительным условиям, указанным как необходимые для этой операции.
Если это предположение считается слишком рискованным (например, в многоканальных или распределенных вычислениях ), обратный подход используется , означающий, что серверный компонент проверяет, выполняются ли все соответствующие предварительные условия (до или во время обработки клиентского компонента запроса ). и в противном случае отвечает соответствующим сообщением об ошибке.
История
[ редактировать ]Этот термин был придуман Бертраном Мейером в связи с разработкой им языка программирования Eiffel и впервые описан в различных статьях, начиная с 1986 года. [ 1 ] [ 2 ] [ 3 ] и два последовательных издания (1988, 1997) его книги «Объектно-ориентированное построение программного обеспечения» . Eiffel Software подала заявку на регистрацию товарного знака Design by Contract в декабре 2003 года, и она была удовлетворена в декабре 2004 года. [ 4 ] [ 5 ] Нынешним владельцем этой торговой марки является Eiffel Software. [ 6 ] [ 7 ]
Проектирование по контракту уходит корнями в работу над формальной верификацией , формальной спецификацией и логикой Хоара . Оригинальные вклады включают в себя:
- Четкая метафора для руководства процессом проектирования
- Применение к наследованию , в частности формализм переопределения и динамического связывания.
- Приложение для обработки исключений
- Соединение с автоматической документацией программного обеспечения
Описание
[ редактировать ]Центральная идея DbC — это метафора того, как элементы программной системы взаимодействуют друг с другом на основе взаимных обязательств и выгод . Эта метафора пришла из деловой жизни, где «клиент» и «поставщик» договариваются о «контракте», который определяет, например, что:
- Поставщик должен предоставить определенный товар (обязательство) и вправе ожидать, что клиент уплатит ему вознаграждение (выгоду).
- Клиент должен оплатить комиссию (обязательство) и имеет право на получение продукта (выгоды).
- Обе стороны должны соблюдать определенные обязательства, такие как законы и правила, применимые ко всем контрактам.
Аналогично, если в объектно метод класса - ориентированном программировании предоставляет определенную функциональность, он может:
- метода Ожидайте, что определенное условие будет гарантировано при входе любым клиентским модулем, который его вызывает: предварительное условие — обязательство для клиента и выгода для поставщика (сам метод), поскольку оно освобождает его от необходимости обрабатывать случаи за пределами предварительное условие.
- метода Гарантируйте определенное свойство при выходе: постусловие — обязательство для поставщика и, очевидно, выгоду (основную выгоду от вызова метода) для клиента.
- Поддерживать определенное свойство, предполагаемое при входе и гарантированное при выходе: инвариант класса .
Контракт семантически эквивалентен тройке Хоара , которая формализует обязательства. Это можно резюмировать «тремя вопросами», на которые проектировщик должен неоднократно ответить в договоре:
- Что предусматривает контракт?
- Что гарантирует договор?
- Что сохраняет контракт?
Многие языки программирования имеют средства для создания утверждений подобных . Однако DbC считает, что эти контракты настолько важны для корректности программного обеспечения , что они должны быть частью процесса проектирования. По сути, DbC рекомендует сначала писать утверждения . [ нужна ссылка ] Контракты могут быть написаны с помощью комментариев к коду , реализованы с помощью набора тестов или и то, и другое, даже если для контрактов не существует специальной языковой поддержки.
Понятие контракта распространяется на уровень метода/процедуры; контракт для каждого метода обычно содержит следующую информацию: [ нужна ссылка ]
- Приемлемые и неприемлемые входные значения или типы и их значения.
- Возвращаемые значения или типы и их значения
- Значения или типы условий ошибок и исключений , которые могут возникнуть, и их значения.
- Побочные эффекты
- Предварительные условия
- Постусловия
- Инварианты
- (реже) Гарантии производительности, например, в отношении используемого времени или пространства
Подклассам в иерархии наследования разрешено ослаблять предусловия (но не усиливать их) и усиливать постусловия и инварианты (но не ослаблять их). Эти правила приблизительно соответствуют поведенческим подтипам .
Все отношения классов существуют между классами клиентов и классами поставщиков. Клиентский класс обязан выполнять вызовы функций поставщика, если результирующее состояние поставщика не нарушается клиентским вызовом. В дальнейшем поставщик обязан предоставить состояние возврата и данные, не нарушающие государственные требования клиента.
Например, буфер данных поставщика может требовать, чтобы данные присутствовали в буфере при вызове функции удаления. Впоследствии поставщик гарантирует клиенту, что, когда функция удаления завершит свою работу, элемент данных действительно будет удален из буфера. Другие контракты на проектирование представляют собой концепции инварианта класса . Инвариант класса гарантирует (для локального класса), что состояние класса будет поддерживаться в пределах заданных допусков в конце выполнения каждой функции.
При использовании контрактов поставщик не должен пытаться проверить выполнение условий контракта — практика, известная как наступательное программирование — общая идея заключается в том, что код должен «сильно давать сбои», а проверка контракта является защитой.
Свойство DbC «жесткий отказ» упрощает отладку поведения контракта, поскольку предполагаемое поведение каждого метода четко указано.
Этот подход существенно отличается от подхода защитного программирования , где поставщик несет ответственность за выяснение того, что делать, если предварительное условие нарушено. Чаще всего поставщик генерирует исключение, чтобы сообщить клиенту, что предварительное условие нарушено, и в обоих случаях — как DbC, так и защитного программирования — клиент должен придумать, как на это реагировать. В таких случаях DbC облегчает работу поставщика.
Проектирование по контракту также определяет критерии правильности программного модуля:
- Если инвариант класса И предусловие истинны до того, как клиент позвонит поставщику, то инвариант И постусловие будет истинным после завершения обслуживания.
- При обращении к поставщику программный модуль не должен нарушать предварительные условия поставщика.
Проектирование по контракту также может облегчить повторное использование кода, поскольку контракт для каждого фрагмента кода полностью документирован. Контракты на модуль можно рассматривать как форму программной документации, определяющей поведение этого модуля.
Влияние на производительность
[ редактировать ]Условия контракта никогда не должны нарушаться во время выполнения безошибочной программы. Поэтому контракты обычно проверяются только в режиме отладки во время разработки программного обеспечения. Позже в выпуске проверки контрактов отключаются для максимизации производительности.
Во многих языках программирования контракты реализуются с помощью Assert . Утверждения по умолчанию компилируются в режиме выпуска в C/C++ и аналогичным образом деактивируются в C#. [ 8 ] и Ява.
Запуск интерпретатора Python с «-O» (для «оптимизировать») в качестве аргумента также приведет к тому, что генератор кода Python не будет выдавать какой-либо байт-код для утверждений. [ 9 ]
Это эффективно устраняет затраты на выполнение утверждений в рабочем коде — независимо от количества и вычислительных затрат на утверждения, используемые при разработке, — поскольку такие инструкции не будут включены в производство компилятором.
Связь с тестированием программного обеспечения
[ редактировать ]Проектирование по контракту не заменяет обычные стратегии тестирования, такие как модульное тестирование , интеграционное тестирование и тестирование системы . Скорее, оно дополняет внешнее тестирование внутренними самотестами, которые можно активировать как для изолированных тестов, так и в рабочем коде на этапе тестирования.
Преимущество внутренних самотестирований заключается в том, что они могут обнаруживать ошибки до того, как они проявятся в виде неверных результатов, наблюдаемых клиентом. Это приводит к более раннему и более конкретному обнаружению ошибок.
Использование утверждений можно рассматривать как форму тестового оракула , способ тестирования проекта путем реализации контракта.
Языковая поддержка
[ редактировать ]Языки с встроенной поддержкой
[ редактировать ]Языки, которые изначально реализуют большинство функций DbC, включают:
- Был 2012 год
- ПРИВЕТ
- Кложур
- Кобра
- Д [ 10 ]
- Дафни
- Эйфелева
- Крепость
- Котлин
- Меркурий
- Oxygene (ранее Chrome и Delphi Prism) [ 11 ] )
- Рэкет (включая контракты более высокого порядка и подчеркивание того, что в нарушениях контрактов виновная сторона должна винить виновную сторону и делать это с точным объяснением) [ 12 ] )
- Сатер
- Скала [ 13 ] [ 14 ]
- SPARK (через статический анализ программ Ada )
- Налить
- ВДМ
Кроме того, стандартная комбинация методов в Common Lisp Object System имеет квалификаторы метода :before
, :after
и :around
которые позволяют, помимо прочего, писать контракты в качестве вспомогательных методов.
Языки со сторонней поддержкой
[ редактировать ]В этом разделе есть несколько проблем. Пожалуйста, помогите улучшить его или обсудите эти проблемы на странице обсуждения . ( Узнайте, как и когда удалять эти шаблонные сообщения )
|
Для существующих языков программирования без собственного дизайна были разработаны различные библиотеки, препроцессоры и другие инструменты по контрактной поддержке:
- Ada через прагмы GNAT для предусловий и постусловий.
- С
- DBC для препроцессора C
- Поиск GNU
- ECV формальной проверки Инструменты
- С++ :
- Boost.Контракт
- eCv++ формальной проверки Инструменты
- Компилятор Digital Mars C++ через CTESK для C расширение
- Библиотека Loki предоставляет механизм ContractChecker, который проверяет, соответствует ли класс проектированию по контракту.
- DBC C++ Проектирование по контракту для C++
- C# (и другие языки .NET) через контракты кода . [ 15 ] ( проект Microsoft Research , интегрированный в .NET Framework 4.0)
- Groovy через GContracts
- Зайдите через dbc или gocontracts.
- Ява :
- Активный:
- OVal с AspectJ
- Контракты для Java (Кофоха)
- Язык моделирования Java (JML)
- Проверка компонента (только предварительные и постусловия) [ 16 ]
- действительный4j
- SafeR (с безопасными ссылками)
- Неактивный/неизвестный:
- Jtest (активен, но DbC, похоже, больше не поддерживается) [ 17 ]
- iContract2/JКонтракты
- Контракт4J
- jПодрядчик
- C4J
- Google CodePro Аналитикс
- SpringContracts для Spring Framework
- Джасс. Архивировано 3 апреля 2003 г. в Wayback Machine.
- Модерн Джасс (преемник - Кофоха) [ 18 ] [ 19 ]
- JavaDbC с использованием AspectJ
- JavaTESK с использованием расширения Java
- chex4j с помощью javassist
- настраиваемые Java-по контрактам
- Активный:
- JavaScript , через декоратор-контракты , AspectJS (в частности, AJS_Validator), Cerny.js, ecmaDebug, jsContract, dbc-code-contracts или jscategory.
- Common Lisp , посредством макросов или CLOS метаобъектного протокола .
- Nemerle , через макросы.
- Nim , via macros .
- Perl через модули CPAN Class::Contract (автор Дэмиан Конвей ) или Carp::Datum (автор Рафаэль Манфреди).
- PHP через PhpDeal , Praspel или ContractLib Стюарта Герберта.
- Python с использованием таких пакетов, как Deal , icontract , PyContracts , dpcontracts или zope.interface . Постоянное изменение Python для поддержки проектирования по контрактам было предложено в PEP-316 в 2003 году, но отложено.
- Ruby через DesignByContract Брайана Маккалистера, Ruby DBC Ruby-contract или Contracts.ruby.
- Ржавчина через ящик с контрактами .
- Свифт через какаопод Джима Бойда .
- Tcl через объектно-ориентированное расширение XOTcl .
См. также
[ редактировать ]- Компонентная разработка программного обеспечения
- Корректность (информатика)
- Оборонительное программирование
- Безотказная система
- Формальные методы
- логика Хоара
- Модульное программирование
- Вывод программы
- Доработка программы
- Строгая типизация
- Разработка через тестирование
- Анализ состояния типов
Примечания
[ редактировать ]- ^ Мейер, Бертран: Проектирование по контракту , Технический отчет TR-EI-12/CO, Interactive Software Engineering Inc., 1986 г.
- ^ Мейер, Бертран: Проектирование по контракту , в «Достижениях в объектно-ориентированной разработке программного обеспечения» , ред. Д. Мандриоли и Б. Мейер, Прентис Холл, 1991, стр. 1–50.
- ^ Мейер, Бертран: « Применение «проектирования по контракту» », в Computer (IEEE), 25, 10 октября 1992 г., стр. 40–51.
- ^ «Регистрация Ведомства США по патентам и товарным знакам «ДИЗАЙН ПО КОНТРАКТУ» » . Архивировано из оригинала 21 декабря 2016 г. Проверено 22 июня 2009 г. [ мертвая ссылка ]
- ^ «Регистрация в Ведомстве по патентам и товарным знакам США графического дизайна со словами «Дизайн по контракту» » . Архивировано из оригинала 21 декабря 2016 г. Проверено 22 июня 2009 г. [ мертвая ссылка ]
- ^ «Статус товарного знака и поиск документов — 78342277» . Получение заявки на регистрацию и регистрацию товарного знака USPTO .
- ^ «Статус товарного знака и поиск документов — 78342308» . Получение заявки на регистрацию и регистрацию товарного знака USPTO .
- ^ «Утверждения в управляемом коде» . Сеть разработчиков Microsoft . 15 ноября 2016 г. Архивировано из оригинала 22 августа 2018 г.
- ^ Официальная документация Python, утверждение утверждения
- ^ Брайт, Уолтер (01 ноября 2014 г.). «Язык программирования D, контрактное программирование» . Цифровой Марс . Проверено 10 ноября 2014 г.
- ^ Ходжес, Ник. «Пишите более чистый и качественный код с помощью контрактов классов в Delphi Prism» . Эмбаркадеро Технологии. Архивировано из оригинала 26 апреля 2021 года . Проверено 20 января 2016 г.
- ^ Финдлер, Контракты Феллейзена для функций высшего порядка
- ^ «Документация стандартной библиотеки Scala — утверждения» . ЭПФЛ . Проверено 24 мая 2019 г.
- ^ Строгая типизация как еще одно «обеспечение соблюдения контракта» в Scala, см. обсуждение на scala-lang.org/ .
- ^ «Кодекс контрактов» . Сеть разработчиков Microsoft . Архивировано из оригинала 15 ноября 2018 года.
- ^ «Спецификация проверки компонента» . beanvalidation.org .
- ^ «Помощь экспертов по тестированию программного обеспечения | Ресурсы Parasoft» (PDF) . Архивировано (PDF) из оригинала 9 октября 2022 г.
- ^ «Архивная копия» (PDF) . Архивировано из оригинала (PDF) 28 марта 2016 г. Проверено 25 марта 2016 г.
{{cite web}}
: CS1 maint: архивная копия в заголовке ( ссылка ) стр. 2 - ^ «Нет шансов выпустить под лицензией Apache/Eclipse/MIT/BSD? · Проблема № 5 · nhatminhle/cofoja» . Гитхаб .
Библиография
[ редактировать ]- Митчелл, Ричард и МакКим, Джим: Проектирование по контракту: на примере , Аддисон-Уэсли, 2002 г.
- Викикнига , описывающая DBC, близкую к исходной модели.
- Макнил, Эшли: Структура семантики поведенческих контрактов . Материалы второго международного семинара по моделированию поведения: основы и приложения (BM-FA '10). ACM, Нью-Йорк, США, 2010. В этой статье обсуждаются обобщенные понятия контракта и взаимозаменяемости .
Внешние ссылки
[ редактировать ]- Сила дизайна по контракту(TM) Описание DbC верхнего уровня со ссылками на дополнительные ресурсы.
- Создание объектно-ориентированного программного обеспечения без ошибок: введение в Design by Contract(TM) Старый материал по DbC.
- Преимущества и недостатки; реализация в RPS-Obix
- Использование контрактов кода для более безопасного кода