Программист-прагматик. Путь от подмастерья к мастеру | страница 97



Кроме того, отсутствует встроенный механизм «старых» значений; т. е. значений, которые существовали на момент входа в метод. При использовании утверждений, обеспечивающих соблюдение условий контрактов, к предусловию необходимо добавить программу, позволяющую сохранить любую информацию, которую вы намерены использовать в постусловии. Сравним это с iContract, где постусловие может просто ссылаться на «variabie@pre», или с языком Eiffel, который поддерживает принцип «old expression».

И наконец, исполняющая система и библиотеки не предназначены для поддержки контрактов, так что эти вызовы не проверяются. Это является серьезным недостатком, поскольку большинство проблем обнаруживается именно на стыке между вашей программой и библиотеками, которые она использует (более детально этот вопрос обсуждается в разделе «Мертвые программы не лгут»).

Поддержка ППК в языках программирования

Языки программирования, в которых имеется встроенная поддержка ППК (например, Eiffel и Sather[URL 12]) осуществляют автоматическую проверку предусловий и постусловий в компиляторе и исполняющей системе. В этом случае вы оказываетесь в самом выгодном положении, поскольку все базовые элементы программы (включая библиотеки)должны выполнять условия соответствующих контрактов.

Но как быть, если вы работаете с более популярными языками типа С, С++, и Java? Для этих языков существуют препроцессоры, которые обрабатывают контракты, инкапсулированные в первоначальный исходный текст как особые комментарии. Препроцессор разворачивает эти комментарии, преобразуя их в программу, которая контролирует утверждения.

Если вы работаете с языками С и С++, то попробуйте изучить Nana [URL 18]. Nana не осуществляет обработку наследования, но использует отладчик во время выполнения программы для отслеживания утверждений новаторским методом.

Для языка Java существует средство iContract [URL 17]. Оно обрабатывает комментарии (в формате JavaDoc) и генерирует новый исходный файл, содержащий логику утверждений.

Препроцессоры уступают встроенным средствам. Они довольно муторно интегрируются в проект, а другие используемые вами библиотеки останутся без контрактов. И тем не менее, они могут принести большую пользу; когда проблема обнаруживается подобным способом – в особенности та, которую по-другому найти просто невозможно, – это уже сродни работе волшебника.

ППК и аварийное завершение работы программы

ППК прекрасно сочетается с принципом аварийного завершения работы программы (см. «Мертвые программы не лгут»). Предположим, что есть метод, вычисляющий квадратные корни (подобный классу DOUBLE в языке Eiffel). Этот метод требует наличия предусловия, которое ограничивает область действия положительными числами. Предусловие в языке Eiffel объявляется с помощью ключевого слова require, а постусловие – с помощью ключевого слова ensure, так можно записать: