Контракт на качество или контрактное программирование

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

Термин "контрактное программирование" был введен Бертраном Мейером, автором языка программирования Eiffel. Этот объектно-ориентированный язык широкого назначения появился в 1986 году. Он не стал мейнстрим-языком, но до сих пор развивается компанией Eiffel Software и имеет свою нишу в облястях, где важна надежность программного обеспечения. Согласно статистике Eiffel Software, 90% ошибок выявляется и исправляется еще на этапе разработки, благодаря встроенной поддержке контрактного программирования.

Eiffel имеет очень интересные возможности, а конструкции контрактного программирования стали его частью с самого начала. Рассмотрим принципы контрактного программирования на примере программы на Eiffel.

      class
          DATE_AD
                  -- Common Era date

      feature
          set (y: INTEGER, m: INTEGER, d: INTEGER) is
                  -- A new date
              require
                  0 

Это листинг класса DATE_AD для хранения даты нашей эры. В блоке "feature {NONE}" определяются три закрытых члена класса для года, месяца и дня. В блоке feature определяется публичный метод set, позволяющий задать дату. В этом методе определены предусловия (блок require), которые проверяют корректность входных параметров. Метод to_string возвращает текстовое представление даты, и в этом методе задано постусловие (блок require), что результат не может быть пустым. В блоке invariant заданы условия на состояние объектов класса DATE_AD. Контракты наследуются производными классами и могут быть расширены новыми, более строгими.

Есть несколько уровней контроля выполнения постусловий, предусловий и инвариантов. На этапе разработки в EiffelStudio можно отслеживать все контракты, а в продакшен режиме мониторинг может быть отключен или использоваться выборочно: только предусловия или только выбранные классы и т.п. В случае нарушения контракта выбрасывается исключение, которое может быть обработано.

Стиль программирования на Eiffel располагает к написанию самодокументируемого кода. Контракты не только контролируются в работе программы, но еще и используются при генерации документации средствами разработки Eiffel. Описание дочерних классов включает контракты всех базовых.

"Контрактное программирование" не ограничивается только Eiffel. Вот известные языки, в которые изначально включены средства контрактного программирования: Ada 2012, Clojure, D, Racket (Plt-Schema). В других языках поддержка контрактного программирования добавлена сторонними библиотеками: C и С++, C#, Java, JavaScript, Lisp, Perl, PHP, Python, Ruby. Не все реализации сопоставимы по возможностям с Eiffel, но даже использование самых простых конструкций контрактного программирования повышает качество кода.

  • Проверка контрактов и на этапе разработки и на этапе эксплуатации.
  • Самодокументируемость программы. Контракт, как неотъемлемая часть кода, документирует интерфейс и особенности работы класса, причем такое описание класса всегда в актуальном состоянии.
  • Декларативное описание контрактов отдельно от методов. Это позволяет сосредоточится на реализации бизнес логики и не тратить усилия на проверку входных параметров и результата, а также сложной логики отслеживания корректности состояния объектов.
  • Контроль непротиворечивости и смысловой целостности иерархии классов. Контракт базового класса может быть ужесточен в производном, но он по-прежнему остается обязательным к выполнению. Если метод возвращает положительное число, то переопределенный метод не может возвращать отрицательные числа.

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

  1. http://docs.eiffel.com – основной сайт документации языка Eiffel и продуктов копании Eiffel Software.
  2. http://en.wikipedia.org/wiki/Design_by_contract – общая информация о контрактном программировании со списком языков и библиотек, поддерживающих этот метод проектирования.
  3. http://docs.racket-lang.org/guide/contracts.html – документация Racket (бывший Plt-Schema), который включает реализацию контрактов более высокого порядка.
Связаться