Контрактное программирование
Контрактное программирование (Design by Contract (DbC), или Programming by Contract) — это метод проектирования программного обеспечения. Он предполагает, что проектировщик должен определить формальные, точные и верифицируемые спецификации интерфейсов для компонентов системы. Метод основан на идее абстрактных типов данных и является концептуальной метафорой контракта в бизнесе. Можно сказать, что это развитие теории абстрактных типов данных.
История
Термин предложил Бертран Мейер в связи с разработкой языка Eiffel. Контрактное программирование выросло из формальной верификации, формальной спецификации и логики Хоара. Контрактное программирование — это не только простая метафора, указывающая способ проектирования. Условия, облегчающие применение контрактного программирования:
- наличие наследования и возможность динамического связывания
- способность обрабатывать исключения
- возможность автоматической документации ПО
Описание
Основная идея контрактного программирования — это модель взаимодействия элементов программной системы, основывающаяся на идее взаимных обязательств и преимуществ. Как и в бизнесе, клиент и поставщик действуют в соответствии с определённым контрактом. Контракт некоторого метода или функции может включать в себя:
- конкретные обязательства, которые любой клиентский модуль должен выполнить перед вызовом метода — предусловия. Эти обязательства клиента дают преимущество для поставщика — он может не проверять выполнение предусловий.
- конкретные свойства, которые должны присутствовать после выполнения метода — постусловия. Это уже обязательства поставщика.
- обязательства по выполнению конкретных свойств — инвариантов. Они должны выполняться при получении поставщиком сообщения, а также при выходе из метода.
Многие языки программирования позволяют учитывать такие обязательства. Контрактное программирование подразумевает эти требования критическими для корректности программ, поэтому они должны быть утверждены при проектировании. Таким образом, контрактное программирование предписывает начинать писать код с написания формальных утверждений корректности (assertions).
В объектно-ориентированном программировании контракт метода обычно включает следующую информацию:
- возможные типы входных данных и их значение
- типы возвращаемых данных и их значение
- условия возникновения исключений, их типы и значения c
- Побочный эффект метода
- предусловия, которые могут быть ослаблены (но не усилены!) в подклассах
- постусловия, которые могут быть усилены (но не ослаблены!) в подклассах
- инварианты, которые могут быть усилены (но не ослаблены!) в подклассах
- (иногда) гарантии производительности, например, временная сложность или сложность по памяти
При использовании контрактов сам код не обязан проверять их выполнение. Обычно в таких случаях в коде делают жёсткое падение («fail hard»), таким образом облегчая отладку выполнения контрактов. Во многих языках такое поведение реализуется оператором assert
. В релизовом варианте кода это поведение может быть сохранено, либо проверки могут быть убраны из-за выигрыша в производительности.
Юнит-тесты проверяют модуль изолированно от других, проверяя, что модуль удовлетворяет предположениям контракта, а также свои контракты выполняют используемые им модули. Интеграционные тесты проверяют, что модули работают корректно вместе.
Контрактное программирование может повысить уровень повторного использования кода, поскольку обязательства модуля чётко документированы. Вообще, контракт модуля можно рассматривать также как способ документации программного обеспечения.
Реализация в языках программирования
Поддержка DbC на языковом уровне
Языки, изначально поддерживающие средства для контрактного программирования:
- Cobra
- D[1]
- Eiffel
- Fortress
- Lisaac
- Nice
- Oxygene (бывший Chrome)
- Sather
- SPARK посредством статического анализа программ на Аде.
- Spec#
- SeC (расширение языка С)
- J@va (расширение языка Java)
Поддержка DbC с помощью сторонних библиотек
- C and C++ посредством CTESK, препроцессора DBC for C, GNU Nana или компилятора C++ от Digital Mars.
- C# посредством Code Contracts
- Java посредством JavaTESK, iContract2, Contract4J, jContractor, Jcontract, C4J, CodePro Analytix, STclass, Jass preprocessor, OVal with AspectJ, Java Modeling Language (JML), SpringContracts для Spring Framework, или Modern Jass, Custos с использованием AspectJ, JavaDbC с использованием AspectJ.
- JavaScript посредством Cerny.js или ecmaDebug.
- Lisp
- Common Lisp с помощью макросов или протокола метаобъектов CLOS.
- Scheme посредством расширения PLT, а именно тот факт, что любое нарушение контракта должно указывать на виновного и иметь точное объяснение.[1]
- Nemerle с помощью макросов.
- Perl с помощью CPAN-модулей Class::Contract (Damian Conway) или Carp::Datum (Raphael Manfredi).
- Python с помощью пакета zope.interface, PyDBC или Contracts for Python.
- Ruby с помощью DesignByContract (от Brian McCallister), Ruby DBC или ruby-contract.
Общие инструменты
- Perfect Developer посредством Perfect specification language может проверять контракт, используя статический анализ кода и генерируя программы на языках типа C++ и Java.
Примечания
- ↑ Bright, Walter D Programming Language, Contract Programming. Digital Mars (2006-08-20). Проверено 6 октября 2006.
См. также
de:Design by contract en:Design by contract eo:Perkontrakta programado es:Diseño por Contrato fi:Sopimuspohjainen ohjelmointi fr:Programmation par contrat it:Design by contract ja:契約プログラミング pl:Programowanie kontraktowe pt:Programação por contrato sk:Design by contract
Если вам нравится SbUP.com Сайт, вы можете поддержать его - BTC: bc1qppjcl3c2cyjazy6lepmrv3fh6ke9mxs7zpfky0 , TRC20 и ещё....