Как вы управляете прыжком сложности?

13

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

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

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

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

Редактировать: Ответ Сумасшедшего Эдди включает в себя «вы смиритесь с этим и найдете самый дешевый способ реализации новой сложности». Это заставило меня задуматься о чем-то, что подразумевалось в этом вопросе, но я специально не поднял.

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

glenatron
источник

Ответы:

8

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

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

Петер Тёрёк
источник
6

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

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

Распределенные вычисления и параллельное программирование добавляют еще два измерения к размеру пространства «сложности», которое увеличивается по крайней мере в кубическом (sp?) (N ^ 3) по сравнению с «нормальным» программированием. Например, подумайте о некоторых новых проблемах и заблуждениях, с которыми нам приходится сталкиваться. Даже играть с идеей, что вы можете понять взаимосвязи и побочные эффекты в этом масштабе, смешно.

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

Некоторые идеи о том, как справиться со всем этим, в дополнение к тому, что уже были рассмотрены в других ответах:

  • Великое смирение
  • Примите, что ваша система / программа несовершенна, непостоянна и неполна .
  • Готовьтесь к ошибкам
  • Принять изменения
  • План резервирования
  • Подумайте о будущем
  • Посмотрите (или изучите) биологию или социологию, как ведут себя сложные системы
  • Старайтесь изо всех сил, чтобы избежать изменчивого состояния. Перейти на протоколы без сохранения состояния (например, REST и HTTP).
  • Функциональное программирование может облегчить часть боли

Я думаю, я мог бы продолжать и продолжать. Очень интересная тема :)

Maglob
источник
Посмотрите (или изучите) биологию или социологию, как ведут себя сложные системы - давай. Остальная часть вашего ответа была твердой, но это имеет такое периферийное применение к описанной проблеме.
Джим Г.
1
@ Джим Г. Возможно. Биология не поможет оптимизировать ваши циклы for, но если вы хотите придумать новые перспективы, идеи или эффективные абстракции (в разработке программного обеспечения), это поможет выйти из песочницы. Утверждая, что биология (или социология) не имеет ничего общего с программированием, она всего в нескольких шагах от того, чтобы утверждать, что ООП или шаблоны проектирования не имеют ничего общего с программированием. Например: ООП : биология -> Алан Кей -> ООП / Smalltalk. Или Шаблоны проектирования : социология -> городской дизайн -> Кристофер Александр -> Язык шаблонов -> Шаблоны проектирования.
Маглоб
@Jim G. Cont. Некоторые цитаты, Алан Кей: «Я думал, что объекты похожи на биологические клетки и / или отдельные компьютеры в сети, могут общаться только с сообщениями», и Википедия: «[Шаблон проектирования] Идея была предложена архитектором Кристофером Александером в область архитектуры [1] и была адаптирована для различных других дисциплин, в том числе информатики "
Маглоб
Хорошо. Я даю вам +1 за Старайтесь изо всех сил, чтобы избежать изменяемого состояния и других самородков. Я хочу сказать, что если ваш менеджер поручил вам снизить сложность, вы наверняка примените бритву Оккама к этой проблеме и приступите к работе. Я не думаю, что вы или кто-либо еще «обратились бы к биологии» за помощью в решении насущной проблемы.
Джим Г.
2

Я не согласен с духом ответа @ Péter Török, потому что он предполагает, что команда (или человек) может предвидеть самые рискованные элементы в начале жизненного цикла проекта. Например, в случае OP команда не могла предвидеть возрастающую сложность, связанную с многопоточным решением, пока их спины не были прислонены к стене.

Вопрос ОП - хороший вопрос, и он говорит о проблеме, с которой сталкиваются многие магазины по разработке программного обеспечения.

Вот как бы я справился с проблемой:

  1. Следуйте советам Фреда Брукса и организуйте своих разработчиков как хирургическую команду .
  2. Выберите мудрого и «доброжелательного» мастера-хирурга, который может одновременно: A) завоевать доверие и уважение своих коллег; и B) принимать трудные решения своевременно.
  3. Ожидайте, что мастер-хирург уменьшит сложность на переднем и заднем концах процесса разработки.

Подробнее о пункте 3:

  1. Мастер-хирург должен приложить сознательные усилия, чтобы предложить самое простое решение, которое будет работать. Годы значимого опыта должны дать возможность мастеру-хирургу сделать это.
  2. Более широкая организация, то есть начальство мастера-хирурга, должна дать команде достаточно времени и ресурсов, чтобы уменьшить сложность после даты отправки. Это позволит команде разработчиков своевременно отправлять код и выполнять кайдзен для постоянного снижения сложности.
Джим Г.
источник
ИМХО в случае ОП они должны были начать тестирование раньше, чтобы выяснить, как (и если) их архитектура работает в реальных условиях. Кстати, предложив , чтобы «главный хирург», вы , кажется, в основном означает , что есть люди , которые могут предвидеть технические риски проекта - точный момент вы претендовать не согласиться.
Петер Тёрёк
@ Петер Тёрёк: ... Предлагая «главного хирурга», вы, по-видимому, в основном подразумеваете, что есть люди, которые могут предвидеть технические риски проекта : нет, я не такой. Я говорю, что эти люди оба: A) лучше всего подходят для того, чтобы вообще избежать сложности; и B) Лучше всего выковыривать команду из сложности после того, как код был отправлен.
Джим Г.
ИМХО речь идет об одном и том же. Опыт, который помогает вашему «главному хирургу» выбрать простейшее решение, которое может работать, основан на воспоминаниях о прошлых проектах и ​​решениях, а также на знании того, какое решение сработало (или не сработало) в каком конкретном случае. Другими словами, он просматривает применимые решения для конкретных проблем и оценивает потенциальные выгоды и риски каждой из них. Это то, что помогает ему выбрать подходящую для текущей ситуации ситуацию, избегая рискованных путей .
Петер Тёрёк
1
Это напоминает мне цитату покойного великого тренера по лошадям Рэя Ханта: «Как вы получаете здравый смысл? Опыт. Как вы получаете опыт? Плохое суждение».
Гленатрон
1

Код для интерфейсов

При написании новых функций, взаимодействующих с другими функциями, создайте границу в виде интерфейса (вид Java), через который все проходят. Это будет

  1. убедитесь, что у вас есть полный контроль над тем, какие функции используются
  2. позволяют иметь несколько реализаций одной и той же функциональности.
  3. уменьшите общую сложность, потому что модули только тонко связаны, а не полностью переплетены.

источник
0

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

Неудивительно.

Это разработка программного обеспечения. Если вы не изобретаете что-то новое, вы загружаете уже проверенное решение.

Там мало среднего.

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

Как это сделать?

  1. Есть реалистичные ожидания. Вы изобретаете что-то новое. Там должны быть части, которые вы не понимаете.

  2. Есть реалистичные ожидания. Если в первый раз все работает правильно, вы что-то упустили.

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

  4. Есть реалистичные ожидания. Вы не можете предсказать будущее очень хорошо.

С. Лотт
источник
2
Подождите, так что вы говорите: есть реалистичные ожидания?
Гленатрон
0

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

Ян
источник
0

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

Эдвард Стрендж
источник
0

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

Тем не менее, здесь есть множество специфических местных факторов, таких как:

  • Цели этой системы. Это одноразовая вещь? Намереваетесь ли вы сохранить эту систему работающей на среднесрочную и долгосрочную перспективу?

Для краткосрочных вещей, возможно, не стоит думать об этом более чем достаточно, чтобы просто запустить его. Рефакторинг стоит дорого, и это то, что не создает немедленной конечной ценности для вашего пользователя. тем не мениеЯ не могу придумать ни одного другого случая, кроме программного обеспечения «абсолютного одноразового использования», когда оно настолько короткое, что не стоит улучшать ваш дизайн. Гораздо важнее быть в состоянии понять, что вы сделали, и исправить это быстро, чем закончить прямо сейчас. Если это на более длительный срок, то он, скорее всего, в конечном итоге окупится (и, возможно, гораздо раньше, чем думают все участники), или наоборот (если этого не сделать, боль будет очень скоро вместо «когда мы должны это исправить»). Я почти испытываю соблазн сказать: «всегда делайте это лучше», но в некоторых случаях это невозможно.

  • Цели команды. Это скорее что-то вроде «сделай это сейчас, любой ценой» или «давай сделаем правильно»?

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

  • Ваше понимание проблемы. Почему предыдущее решение не сработало?

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

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

Хуан Карлос Кото
источник