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

Изрядную часть свободного времени я тратил на обдумывание дизайна игры, написание пояснений в учебнике и изучение компьютерной графики. Проблема в том, что в этих занятиях я фокусировался на вещах, которые мне было легче понять. Мне нравилось продумывать игровую механику — например, способ нанесения урона игроку. Я проработал этот вопрос на очень детальном уровне — во многих случаях спускаясь к названиям классов C++ и, конечно же, излагая правила расчета. Что касается графики, я сосредоточился на попытке заставить примитивы перемещаться по экрану с помощью OpenGL, потому что движущиеся объекты казались неотъемлемой частью разработки игр. Это все происходило там, где не были определены ни сеттинг, ни даже ключевые особенности игры — с жанром я с трудом определился. Вместо того, чтобы смотреть на эти высокоуровневые концепты игры, я уловил детали, которые мог легко засунуть себе в голову, даже не понимая, из каких ключевых строительных блоков мне придется конструировать видеоигру. Говоря языком алгоритмов, я выполнял поиск в глубину, не желая слишком видеть все дерево, которое мне в конечном итоге придется пройти.

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

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

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

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

Хотя у меня достаточно опыта разработки и написания, чтобы понять эти вещи, иногда я все еще использую подход «сначала детали», где более уместен поиск в ширину. В какой-то степени это происходит потому, что всегда есть стремление к результатам, а путь в глубину всегда кажется коротким и ясным — до тех пор, пока вы не начнете идти. Но в то же время может быть и так, что при отсутствии правильных слов для различения двух стратегий меня ничто не заставляло делать осознанный выбор — аналогия с поисковыми алгоритмами пришла ко мне совсем недавно. В дополнение к тому, что выбор становится ясно видимым, он также дает критерии для выбора одного из двух подходов. Когда вам нужно придумать хорошее решение или просто понять большую и потенциально сложную проблему, поиск в ширину будет работать лучше — теория утверждает, что он гарантирует наилучший возможный результат. Однако, если вам нужен результат заранее и его качество не слишком заботит вас — например, при создании быстрого прототипа, чтобы получить представление о внешнем виде будущего продукта — вам лучше использовать метод «сначала в глубину». поиск, так как он обычно дает результат быстрее. Звучит очевидно, но каким-то образом просто иметь в виду эту аналогию с миром алгоритмов, кажется, облегчает задачу выбора правильного подхода к любой проблеме.