Недавно я открыл для себя Design by Contract (DbC) и считаю, что это чрезвычайно интересный способ написания кода. Среди прочего, казалось бы, предложить:
- Лучшая документация. Поскольку договор является документацией, он не может быть устаревшим. Кроме того, поскольку в контракте конкретно указывается, что делает подпрограмма, это помогает поддерживать повторное использование.
- Упрощенная отладка. Поскольку выполнение программы прекращается в тот момент, когда контракт не выполняется, ошибки не могут распространяться, и конкретное нарушенное утверждение, вероятно, будет выделено. Это предлагает поддержку во время разработки и во время обслуживания.
- Лучший статический анализ. DbC - это просто реализация логики Хоара, и должны применяться те же принципы.
Затраты, по сравнению с ними, кажутся довольно небольшими:
- Дополнительный отпечаток пальца. Поскольку контракты должны быть прописаны.
- Требуется некоторое обучение, чтобы освоиться с написанием контрактов.
Теперь, будучи знакомым в первую очередь с Python, я понимаю, что на самом деле можно написать предварительные условия (просто выбрасывая исключения для несоответствующего ввода) и даже можно использовать утверждения для повторного тестирования определенных постусловий. Но невозможно смоделировать определенные функции, такие как «старый» или «результат», без какой-либо дополнительной магии, которая в конечном счете будет считаться непифонической. (Кроме того, есть несколько библиотек, которые предлагают поддержку, но в конечном итоге я понимаю, что было бы неправильно использовать их, как это делают большинство разработчиков.) Я предполагаю, что это аналогичная проблема для всех других языков (кроме, конечно, Эйфелева).
Моя интуиция подсказывает мне, что отсутствие поддержки должно быть результатом какого-то отказа от практики, но поиск в Интернете не был плодотворным. Мне интересно, может ли кто-нибудь объяснить, почему большинство современных языков так мало поддерживают? Является ли DbC ошибочным или чрезмерно дорогим? Или это просто устарело из-за экстремального программирования и других методологий?
источник
Ответы:
Возможно, они поддерживаются практически на каждом языке программирования.
То, что вам нужно, это «утверждения».
Они легко кодируются как «если»:
При этом вы можете писать контракты, размещая такие утверждения в верхней части кода для ограничений ввода; те в точках возврата являются выходными ограничениями. Вы даже можете добавить инварианты в свой код (хотя на самом деле они не являются частью «дизайна по контракту»).
Поэтому я утверждаю, что они не получили широкого распространения, потому что программисты слишком ленивы, чтобы их кодировать, а не потому, что вы не можете этого сделать.
Вы можете сделать их немного более эффективными в большинстве языков, определив логическую константу во время компиляции «check» и немного изменив операторы:
Если вам не нравится синтаксис, вы можете прибегнуть к различным методам абстракции языка, таким как макросы.
Некоторые современные языки дают вам хороший синтаксис для этого, и я думаю, что вы подразумеваете под «поддержкой современного языка». Это поддержка, но довольно тонкая.
Большинство современных языков не дают вам «временных» утверждений (над произвольными предыдущими или последующими состояниями [временный оператор «в конце концов»)], которые вам нужны, если вы хотите написать действительно интересные контракты. Операторы IF не помогут ты здесь.
источник
super
метод и, возможно, выбросить результаты, если хотите, чтобы контракты проверялись без дублирования. Это действительно помогает реализовать чистый LSP-совместимый код.Как вы говорите, Design by Contract - это функция в Eiffel, которая долгое время была одним из тех языков программирования, который пользуется уважением в сообществе, но никогда не завоевывал популярность.
DbC не существует ни в одном из самых популярных языков, потому что только относительно недавно сообщество основных программистов пришло к выводу, что добавление ограничений / ожиданий в их код является "разумной" вещью, которую ожидают программисты. В настоящее время программисты обычно понимают, насколько ценным является модульное тестирование, и это приводит к тому, что программисты все чаще принимают код для проверки своих аргументов и видят преимущества. Но десятилетие назад, вероятно, большинство программистов сказали бы: «Это просто дополнительная работа для вещей, которые, как вы знаете, всегда будут в порядке».
Я думаю, что если бы вы пришли сегодня к среднему разработчику и поговорили о постусловиях, они бы с энтузиазмом кивнули и сказали: «Хорошо, это похоже на юнит-тестирование». И если вы говорите о предварительных условиях, они скажут: «Хорошо, это похоже на проверку параметров, что мы не всегда делаем, но, знаете, я думаю, что все в порядке ...» А потом, если вы говорите об инвариантах , они начали бы говорить: «Ну и дела, сколько это накладных расходов? Сколько еще ошибок мы собираемся поймать?» и т.п.
Так что я думаю, что еще очень далеко до того, как DbC будет широко принят.
источник
Ложь.
Это практика дизайна . Он может быть явно воплощен в коде (стиль Эйфелевой) или неявно в коде (большинство языков) или в модульных тестах. Практика проектирования существует и работает хорошо. Языковая поддержка по всей карте. Однако он присутствует на многих языках в рамках модульного теста.
Это дорого. А также. Что еще более важно, есть некоторые вещи , которые не могут быть доказаны в данном языке. Например, завершение цикла не может быть доказано на языке программирования, оно требует возможности проверки «более высокого порядка». Так что некоторые виды контрактов технически невыразимы.
Нет.
Мы в основном используем модульные тесты, чтобы продемонстрировать, что DbC выполняется.
Для Python, как вы заметили, DbC работает в нескольких местах.
Результаты испытаний документации и документации.
Утверждения для проверки входов и выходов.
Модульные тесты.
Дальше.
Вы можете использовать грамотные инструменты в стиле программирования, чтобы написать документ, который включает вашу информацию о DbC и который генерирует чистые скрипты Python плюс модульный тест. Подход грамотного программирования позволяет вам написать замечательную литературу, которая включает в себя контракты и полный источник.
источник
there are some things which cannot be proven
. Формальная проверка может быть хорошей, но не все поддается проверке! Так что эта функция на самом деле ограничивает возможности языка программирования!Просто угадай. Возможно, одна из причин того, что он не так популярен, потому что «Дизайн по контракту» является торговой маркой Eiffel.
источник
Одна из гипотез состоит в том, что для достаточно большой сложной программы, особенно с движущейся целью, масса самих контрактов может стать столь же глючной и трудной для отладки, или даже более того, чем только программный код. Как и в случае с любым другим шаблоном, вполне возможно, что после прошлой убывающей отдачи использование будет иметь явные преимущества при более целенаправленном использовании.
Другой возможный вывод состоит в том, что популярность «управляемых языков» является текущим доказательством поддержки разработки по контракту для этих выбранных управляемых функций (ограничения массивов по контракту и т. Д.)
источник
Причина, по которой большинство основных языков не имеют функций DbC в языке, заключается в том, что соотношение цены и выгоды от его реализации слишком велико для разработчика языка.
одна сторона этого уже рассматривалась в других ответах, модульные тесты и другие механизмы времени выполнения (или даже некоторые механизмы времени компиляции с мета-программированием шаблона) уже могут дать вам большую пользу от DbC. Поэтому, хотя выгода есть, она, скорее всего, выглядит довольно скромной.
Другая сторона - это стоимость, поэтому встраивание DbC в существующий язык, скорее всего, является слишком серьезным изменением и очень сложным для загрузки. Ввести новый синтаксис в язык, не нарушая старый код, сложно. Обновление существующей стандартной библиотеки для использования таких далеко идущих изменений будет дорогостоящим. Поэтому мы можем сделать вывод, что реализация функций DbC на существующем языке имеет высокую стоимость.
Я также хотел бы отметить, что концепции, которые в значительной степени являются контрактами для шаблонов и, следовательно, в некоторой степени связаны с DbC, были исключены из новейшего стандарта C ++, поскольку даже после нескольких лет работы над ними было подсчитано, что им все еще нужны годы работы. Такие большие, широкие и радикальные изменения в языках слишком сложно реализовать.
источник
DbC будет использоваться более широко, если контракты можно будет проверить во время компиляции, чтобы было невозможно запустить программу, которая нарушила какой-либо контракт.
Без поддержки компилятора «DbC» - это просто другое имя для «проверки инвариантов / предположений и выдачи исключения в случае нарушения».
источник
У меня есть простое объяснение, большинство людей (включая программистов) не хотят дополнительной работы, если они не считают это необходимым. Программирование авионики, где безопасность считается очень важной, я не видел большинство проектов без нее.
Но если вы рассматриваете программирование для веб-сайтов, настольных компьютеров или мобильных устройств - сбои и неожиданное поведение иногда не считаются плохими, и программисты просто избегают дополнительной работы, когда сообщение об ошибках и последующее их исправление считается достаточным.
Вероятно, это причина, по которой я думаю, что Ada никогда не выбиралась за пределы индустрии авиационного программирования, потому что она требует больше работы в области кодирования, хотя Ada - потрясающий язык, и если вы хотите создать надежную систему, это лучший язык для работы (за исключением SPARK, который является частной язык на основе ада).
Проектирование контрактных библиотек для C # было экспериментальным для Microsoft, и они очень полезны для создания надежного программного обеспечения, но они никогда не набирали обороты на рынке, иначе вы бы видели их сейчас как часть основного языка C #.
Утверждения - это не то же самое, что полностью функциональная поддержка условий до / после и инвариант. Хотя он может пытаться эмулировать их, но язык / компилятор с надлежащей поддержкой выполняет анализ «абстрактного синтаксического дерева» и проверяет логические ошибки, которые просто не могут быть подтверждены.
Изменить: я выполнил поиск, и последующее связанное обсуждение может быть полезным: https://stackoverflow.com/questions/4065001/are-there-any-provable-real-world-languages-scala
источник
Главным образом причины следующие:
источник