Что вы делаете, если попадаете в тупик разработки в таких эволюционных методах, как Agile или XP?

11

Когда я читал знаменитое сообщение в блоге Мартина Фаулера Is Design Dead? Одно из поразительных впечатлений, которые я получил, заключается в том, что, учитывая тот факт, что в Agile Methodology and Extreme Programming дизайн, а также программирование эволюционируют, всегда есть точки, в которых необходимо провести рефакторинг.

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

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

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

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

Дипан Мехта
источник

Ответы:

17

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

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

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

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

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

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

Я только пытаюсь сказать, что считаю себя достаточно приличным в разработке программного обеспечения. В то же время, если бы вы попросили меня написать 100-страничный проектный документ, передать его кодировщику и ожидать, что он будет работать, я, вероятно, не смогу оформить себя из бумажного пакета. Приступая к работе, я иногда набрасывал несколько UML-подобных (очень упрощенных, не полноязычных) диаграмм, но, как только я начну кодировать, я буду рефакторинг по мере необходимости, и мой окончательный код никогда не будет выглядеть так, как я нарисовал изначально. Даже если я потрачу месяц или два на размышления о каждой мелочи, я не могу представить, чтобы кто-то еще мог взять мои диаграммы и придумать солидную часть программного обеспечения, не изменяя дизайн, поскольку они кодируют.

На другом конце спектра, в настоящее время в моей команде (сейчас это гибко, и я полностью поддерживаю это), у нас есть пара парней, которые присоединились к нам со встроенной земли, где они только делали C в течение последних 15 лет. Я, очевидно, помог с некоторым начальным планированием и планированием классов, но я также удостоверился, что продолжу проводить регулярные обзоры кода и мозговые штурмы, где мы обсуждаем приложения SOLID и принципы проектирования. Они действительно произвели некоторый код спагетти, который заставил меня немного съежиться, но с небольшим толчком от меня, они начали рефакторинг того, что уже было произведено, и забавно то, что один из них вернулся ко мне несколько дней спустя и сказал, что я ненавижу сказать это, но после перемещения этого кода, это выглядит намного более читабельным и понятным. Тупик предотвращен. Точка I ' Я пытаюсь сделать так, чтобы даже тот, кто совершенно не знаком с ОО, мог создавать несколько приличный код, если у него есть наставник с большим опытом, чтобы напомнить ему, что «эволюционный дизайн» - это не то же самое, что «отсутствие дизайна». И даже некоторые из его «более сложных» классов не так уж страшны, потому что каждый класс не несет такой большой ответственности (т.е. не так много кода), так что худшее становится хуже, если этот один класс «тупиковый», мы бросьте его и напишите класс замены, который имеет такой же общедоступный интерфейс (до сих пор я никогда не видел необходимости в этой непредвиденной ситуации во всем, что мы писали, и я делал обзоры кода два раза в неделю).

В заключение, я также твердо верю в проектные документы (по крайней мере, для бизнес-условий моей текущей команды), но основная цель для наших проектных документов - Организационная память , поэтому фактические документы пишутся после того, как код произведен и переработан. Перед кодированием у нас обычно есть быстрая (иногда не такая быстрая) фаза проектирования, когда мы набрасываем классы на салфетках / mspaint / visio, и я всегда напоминаю людям, что эта фаза дает путь, а не план, и когда они начинают кодировать, все, что не имеет смысла, должно быть изменено. Даже с этими напоминаниями новые парни стараются втиснуть код в оригинальный дизайн, независимо от того, насколько это неестественно для них. Это обычно появляется в обзорах кода.

Черт, я много писал. Прости за это.

DXM
источник
1
+1 Это стоило того за каждое слово. Я сталкиваюсь с этими ситуациями, как вы описали, и после того, как крайний срок соблюден, попросите их очистить (читай рефакторинг) больше от того, что я считаю здравым смыслом дизайна. Но часто люди повторяют один и тот же вопрос: почему я снова делаю то же самое? Полагаю, теперь у меня есть ответ - если вам нужно быстрее выйти на рынок и позволить дизайну развиваться, рефакторинг - это не компенсация за ваши старые грехи, а фактически законная вещь.
Дипан Мехта
Да, вы много писали, но это было хорошо. Очень понравилось читать :).
Раду Мурзеа
11

Я бы сказал, что феномен «тупика дизайна» ортогонален гибким методам. Я имею в виду, что можно сделать водопад, потратить много времени заранее на (плохой) дизайн. Затем потратьте много времени на его реализацию, чтобы оказаться в тупике.

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

Обратная сторона заключается в том, что даже в гибких методах важно иметь жизнеспособное видение для проектирования системы, которое приводит решения от итерации к итерации. Я думаю, что Кен Шваббер сказал что-то вроде: если у вас есть команда ужасных разработчиков, они будут производить плохое ПО последовательно итеративно. Agile просто означает, что вы не тратите много времени заранее, потому что вы ограничены в том, что вы можете выучить или вообразить, прежде чем приступить к реализации ( и требования также меняются). Тем не менее, в некоторых ситуациях вы должны выполнить предварительную работу (например, исследования), а затем вы должны это сделать.

Как избежать тупиков?

Я бы сказал, в основном, предвидя будущие требования. Это то, что вы получаете с опытом и знакомством с аналогичными проектами / продуктами. Это отчасти то, что помогает вам создать хороший дизайн, потому что вы задаете себе много вопросов «что если» о вашей нынешней системе. Для меня это важнейший компонент. Такие техники, как ОО, просто помогают вам, когда вы уже знаете, что делаете.

Что вы делаете, если у вас тупик?

А «тупиковый» не отличается от любого другого технического блока , который вы будете ударил во время разработки чего - либо , что является новым. Первое, что нужно понять, - это то, что на самом деле нет настоящих «тупиков», которые заставили бы вас полностью отказаться. По крайней мере, ваше обучение до этого момента - это то, что позволяет вам двигаться вперед, чтобы ваши усилия не пропали даром. Когда вы попадаете в тупик, у вас есть проблема . Проблема заключается в том, что нужно изменить, чтобы удовлетворить некоторые новые (или старые) требования, и как оптимизировать внесение этих изменений. Все, что вам нужно сделать сейчас, это решить эту проблему. Будьте благодарны, что это программное обеспечение, а не, например, дизайн самолета, потому что изменение намного проще. Определите проблемы, исправьте их == refactor == разработка программного обеспечения. Иногда много работы происходит ...

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

Несколько известных больших изменений в мире ОС, которые приходят мне в голову:

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

Гай Сиртон
источник
На самом деле ранние версии Windows NT реализовали «Hardware Extract Layer» и поддерживали DEC Apha, а также x86. Поскольку никто никогда не покупал машины на основе альфа-версии DEC, это было тихо отброшено Я полагаю, что эта «независимость от машины» все еще существует в рудиментарном формате в текущем выпуске, поэтому порт ARM может быть не таким уж сложным.
Джеймс Андерсон
3

Я постоянно занимаюсь рефакторингом своих проектов, а также использую диаграммы классов UML. Я имею в виду, что я создаю одну или несколько диаграмм классов по пакетам. Каждая диаграмма сохраняется в корне пакета. Каждый классификатор UML имеет собственный идентификатор, который сопоставляется с соответствующим идентификатором Java. Это означает, что когда я открываю свою диаграмму, она автоматически обновляется до последних изменений рефакторинга кода. Я также могу напрямую изменять свои диаграммы классов на графическом уровне, и весь мой проект немедленно подвергается рефакторингу. Это работает довольно хорошо, но никогда не заменит человека. Моя диаграмма классов UML также является только графическим представлением моего кода. Очень важно не смешивать код и модель, как это делает EMF eclipse, потому что как только рефакторинг будет выполнен, информация о модели также будет потеряна. Я никогда не использую генератор кода, управляемый моделями, потому что это бесполезно. Я не

Сказав, что наличие более 100 диаграмм классов, представляющих все детали структуры моего проекта и полных заметок, очень полезно. Я создаю диаграммы классов только для проектов, потому что обычно у разработчиков нет времени изучать или использовать другие диаграммы. Диаграммы классов также очень хороши, потому что автоматически обновляются. Диаграммы классов могут быть созданы после кода, просто перевернув пакет и добавив примечания. Это быстро и всегда точно и 100% итеративно.

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

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

UML_GURU
источник
1
+1, чтобы показать идею почтового кода UML! Интересно, что мы никогда не вернемся к диаграммам документов после кода!
Дипан Мехта
Да, это именно та проблема, связанная с разработкой на основе моделей, связанной с UML. Вы генерируете документацию, а затем никогда не используете ее, если какая-либо модификация проекта. Объединение модели и кода позволяет нам использовать UML и изменять его столько раз, сколько нам нужно.
UML_GURU
3

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

Я подходил к каждому случаю одинаково, который, казалось, работал хорошо:

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

Расходы:

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

Выгоды:

  • по крайней мере, на порядок меньше риска, потому что у вас все еще есть старый рабочий дизайн / код
  • быстрее выводить на рынок любые функции от 1 до n-1, не требующие полной модернизации
  • если продукт / код умирает до того, как вы полностью завершите редизайн, вы сэкономите разницу во времени разработки
  • итеративный подход и все преимущества в нем
dietbuddha
источник
2

Примерно месяц или два назад наш текущий проект немного застрял из-за некоторых неудачных дизайнерских решений (и отсутствия большого количества дизайна в одном месте) со стилем разработки SCRUM.

Наше решение (и то, что я считаю стандартным для SCRUM) заключалось в том, чтобы посвятить весь спринт (~ 2 недели) только рефакторингу. За это время не было добавлено никакой новой функциональности, но мы смогли подумать о текущей кодовой базе и спроектировать гораздо лучшую систему для того, что мы делаем.

Теперь мы преодолели это препятствие и снова добавляем новые функции.

Izkata
источник
Это еще одно большое трение, чтобы найти. Необходимость сказать клиенту - что мы сейчас создаем то же самое - функций, которые не являются чем-то новым, после передачи первой версии! Как часто и часто (если вообще) вы можете позволить себе сказать это клиенту? или как ты вообще объяснишь?
Дипан Мехта
У вас есть два основных варианта, либо сначала вы просто говорите простую правду - что то, что у вас есть, работает беспорядочно, и его нужно привести в порядок, или, во-вторых, вы говорите, что создаете инфраструктуру для поддержки текущего развития ( что не менее верно, но вращается, чтобы быть немного более позитивным). Вы можете обернуть оба этих вопроса, сказав, что для обеспечения функциональности у нас возник технический долг, который теперь необходимо погасить.
Мерф
@Dipan Mehta: Хорошо, предположим, что клиент хочет двухэтажный дом. Вы проектируете это и доставляете это. Тогда они хотят иметь четыре дополнительных этажа. Вы говорите, ну, я должен потратить это время только на то, чтобы сделать нынешнее здание более надежным, чтобы оно вмещало четыре дополнительных этажа. Поэтому я не думаю, что это должно быть проблемой для клиента, если первоначальный план включал только два этажа. Если шесть этажей были запланированы с самого начала, то да, это может быть проблемой, чтобы сказать клиенту.
Giorgio
@DipanMehta Нам также немного повезло, что клиенты не обязательно знают об этом проекте. Это обновление продукта, который они используют в настоящее время, с почти неопределенной датой завершения около конца этого года. Таким образом, им даже не нужно знать о задержке рефакторинга;) (Менеджер, выполняющий большинство проектных решений, является внутренним)
Izkata
2

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

Кевин Клайн
источник
2

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

Например, Netflix имеет функцию профиля, где разные члены семьи могут выставлять счета на один и тот же план, но имеют отдельные очереди. Несколько лет назад они объявили, что должны будут отменить эту функцию, потому что только около 10% их пользователей использовали ее, но из-за взломанной реализации она поглощала чрезмерное количество работ по обслуживанию. После скандала они укусили пулю и сделали дорогой редизайн, чтобы удержать этих клиентов.

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

Карл Билефельдт
источник
1

Разве это не был Фред Брукс, который сказал что-то вроде «Планирую выбросить первого»? Не думайте слишком об этом, тупиковые проекты также появляются в проектах, которые также стараются выполнить весь дизайн заранее. Перепроектирование происходит во всех типах разработки, будь то из-за того, что это был неосуществимый дизайн с самого начала (последние 20%, которые приукрашиваются из-за «дьявола в деталях») или из-за того, что покупатель меняет фокус. Нет необходимости в тревожных звонках, не беспокойтесь.

скоро
источник