.NET Fest: полная программа конференции на сайте. Присоединяйся к самому большому .NET ивенту
×Закрыть

Программирование по контракту

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

LinkedIn
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Вот на тему глубокого дебага — как раз проверка выполнения контракта является нормальной там, где разработчики или слишком ленивы, чтобы сидеть в отладчике (привет Луговскому), или не в состоянии, например, потому что софт выполняется на далёком сервере и обрабатывает в реалтайме сотни параллельных сущностей (как на моих работах). Реализуется это уже способом, специфичным для языка, платформы и обстановки: где-то это просто assert, где-то вывод в лог, где-то увеличение счётчика... главное, чтобы проблема была известна и опознавалась (хотя бы до такого уровня, чтобы в следующей версии плавно углубиться в неё). Фактически, я отладчик как инструмент не запускал на своих задачах уже... мнэээ... лет 10:) Вижу его только у дочки на задачах по информатике (когда задача тривиальна, но требуется понять, что именно нужно).

К ссылке про контракты в Аде — оно очень похоже выглядит в Erlang. Например, если функция foo должна получать на входе список, достаточно записать её определение в виде

foo(L) when is_list(L) ->

...

вместо простого

foo(L) ->

...

и рантайм автоматически проверит (точнее, он будет искать подходящее определение, но для foo(X) с X не списком он его не найдёт и будет исключение типа function_clause).

Подозреваю наличие аналогичных средств в других ФЯ, но не видел.

Схожие средства я применял в случае особо тяжело понимаемого кода, например, если я знаю, что функция должна вернуть record(nns), пишу

NewNNS = #nns{} = process_message(Message, OldNNS)

и в рантайме выполняется соответствующая проверка.

Для статических компилируемых языков, конечно, больше подходит статический анализ кода. Многие из подобных средств позволяют описать контракт для кода (что на входе, что на выходе, для промежуточных точек) и анализатор по каждому пункту может сказать выполняется // не выполняется // не может проверить.

Это я чуть пробежался по теме «мысью по древу», она значительно обширнее, но описал практически важные «в среднем по больнице» вехи. Главное — не бойтесь форсировать в коде проверку выполнения условия конкретного контракта, по крайней мере в отладочных сборках; это поможет не только отладке, но и чтению.

Спасибо:)

я как — то применял ассерты встроенные в джаве, работают хорошо, если работают поверх юнит-тестирования.

Ну, был такой язык Ейфель, разработанный Бертраном Мейером (автор книги Object-Oriented Software Construction), но как-то не прижилось. Развитие данной темы видится в функциональных зависимостях(а точнее похожая концепция), которые по крайней мере имеют математическое обоснование.

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

Например, простейший вид контракта — может ли метод возвращать нулл. Соответственно если контракт не учитывается, то получаем нуллпойнтер на ровном месте. Исходя из своего опыта я пришел к необходимости четкого документирования контракта любого метода, хотя бы документирования.

Также особенно явно контракты видны в случае веб-сервисов.

тут ТДД, или просто обильное юнит тестирование в помощь.

Ну юнит-тесты понятное дело, помогут, без сомнения. Но они проверяют скорее работоспособность вообще кода в целом, то есть тест проверяет результаты поведения на основании неких данных. Но юнит-тесты требуют времени при написании, тогда как простое документирование и соблюдение контрактов, а главное, вообще понимание контрактов, позволяет сократить бажность программ без особых временных затрат.

То есть я просто смотрю на контракты как на мыслительный способ представления программ и компонентов.

какраз юнит тесты используют в первую очередь как документацию+проверяние контракта. Ибо внести в привычку содержать в порядке жавадок — невероятно тяжело.

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

Ну в целом это не совсем контракт — это как — бы проверка полезной нагрузки метода.

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

Ну а джавадок — уж темболее не контракт. Есть какието языки с поддержкой программирования по контракту (помню в Д такое было), но они шото не на слуху.

Да, джавадок не контракт, в джаве есть ассерты — именно встроенные, типа assert ... — они являются средством программирования по контракту — поддерживают предусловия, постусловия и инварианты.

Подписаться на комментарии