Процесс программирования псевдокода против разработки, основанного на тестировании

Для тех, кто не читал Code Complete 2, процесс программирования псевдокода - это, в основном, способ разработки процедуры, описывая ее на простом английском языке, а затем постепенно пересматривает ее до более подробного псевдокода и, наконец, кодировать. Главное преимущество этого заключается в том, чтобы помочь вам оставаться на правильном уровне абстракции, строя системы сверху вниз, а не снизу вверх, тем самым развивая чистый API в отдельных слоях. Я нахожу, что TDD менее эффективен в этом, потому что он слишком сильно фокусируется на минимальном минимуме, чтобы пройти тест, и поощряет небольшой предварительный дизайн. Я также считаю, что необходимость поддерживать набор модульных тестов для нестабильного кода (код, который постоянно реорганизуется) довольно сложна, потому что обычно бывает, что у вас есть дюжина модульных тестов для процедуры, которая нужна только один или два раза. Когда вы делаете рефакторинг - например, меняете подпись метода - большая часть вашей работы заключается в обновлении тестов, а не в коде prod. Я предпочитаю добавлять модульные тесты после того, как компонентный код немного стабилизировался.

Мой вопрос - тех, кто пробовал оба подхода, которые вы предпочитаете?

Ответы

Ответ 1

Моя команда смешивает оба подхода, и это потрясающий способ развития (по крайней мере для нас). Нам нужны модульные тесты, потому что у нас есть большая и сложная программная система. Но процесс программирования псевдокода - это лучший подход к разработке программного обеспечения, с которым я столкнулся. Чтобы они работали вместе:

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

Красота заключается в том, что к тому времени, когда мы на самом деле пишем код, большая часть работы по реализации уже выполнена, потому что многое из того, что мы считаем реализацией, - это на самом деле дизайн кода. Кроме того, ранний процесс заменяет необходимость в UML-классе и методах работы с дескрипторами, а также фактически будет использоваться. И мы всегда остаемся на соответствующем уровне абстракции.

Очевидно, что процесс никогда не бывает столь же линейным, как я описал, - некоторые причуды реализации могут означать, что нам нужно пересмотреть дизайн на высоком уровне. Но в целом, к тому времени, когда мы пишем модульные тесты, дизайн действительно довольно стабилен (на уровне метода), поэтому не нужно много перезаписывать тесты.

Ответ 2

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

Затем начните тестирование проблемы. После того, как вы проведете тест, начните его прохождение. Если это непросто сделать, вам может потребоваться пересмотреть свой первоначальный план. Если есть проблемы, просто пересмотреть. Тест не существует, чтобы определить решение, которое оно там позволяет вам вносить изменения, чтобы вы могли иметь лучшее решение, гарантируя стабильность.

Я бы сказал, что лучше всего использовать TDD. Ключ должен понять, что TDD не означает "пропустить планирование". TDD означает небольшую часть планирования, чтобы начать работать, и при необходимости отрегулировать. Вам даже не нужно настраивать.

Ответ 3

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

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

Ответ 4

Я использовал оба варианта вместе с Big Upfront Development, все три имеют свои места в зависимости от таких вопросов, как язык, динамика команд и размер/сложность программы.

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

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

Если вы работаете в одиночку на чем-то маленьком на статично типизированном языке, подход к списку является разумным и сэкономит вам много времени на TDD (обслуживание тестирования НЕ бесплатное, хотя писать тесты в первую очередь isn "Не так уж плохо". Если в системе, в которой вы работаете, нет никаких тестов, добавление тестов не всегда восхищается, и вы можете даже привлечь какое-то нежелательное внимание.

Ответ 5

Просто потому, что тест проходит, не означает, что вы закончили.

TDD лучше всего характеризуется Red - Green - Refactor.

Испытание дает одну (две) линии цели. Это всего лишь первый, минимальный набор требований. Реальная цель - та же самая цель, что и "Процесс программирования псевдокода" или любая проектная дисциплина.

Кроме того, TDD управляется тестированием, но это не означает, что он слепо тестируется. Вы можете повторить тестирование таким же образом, как и ваш код. Здесь нет места для догматической приверженности туманному плану. Это гибкая техника - это означает адаптировать ее к вашей команде и вашим обстоятельствам.

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

Реальная цель - хорошее программное обеспечение. TDD не может исключить "доброту".

Техника не является ограничительным мандатом. Методы следует рассматривать как костыль, чтобы помочь вам получить хороший код. Если бы я был умнее, богаче и красивее, мне бы не понадобилось TDD. Но поскольку я такой же тупой, как и я, мне нужен костыль, чтобы помочь мне в рефакторе.

Ответ 6

Для меня TDD имеет псевдокодирование с тузом, которое просто не может конкурировать - как помочь вам абстрактно, так и спланировать разработку, но как только вы закончите разработку на земле TDD, у вас все еще есть модульные тесты.

AS полезный подход, поскольку CC2 описывает псевдокодирование, оно просто не может сравниться с этим. TDD составляет всего лишь половину от проектирования, а также обеспечивает строгий эшафот, с которого вы можете продвинуть проект вперед. Однако я не вижу причин, по которым вы не можете псевдокод для решения проблем TDD.

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

(пожалуйста, не плачьте меня за это, я только наполовину серьезен: P)