Книга: Постигая Agile
Назад: Акт IV. Работа в сверхурочное время, часть 2: снова сверхурочные
Дальше: Принимать решения по коду и проекту в последний ответственный момент

Код и архитектура

В ходе работ над проектом Chrysler Comprehensive Compensation (C3) Кенту Беку было необходимо изменить корпоративную культуру команды, переключив ее с создания «умного» кода на простые решения, а это весьма сложная задача. Один из методов, который он использовал, – это церемония давления со стороны коллег. Например, группа торжественно шествовала к человеку, придумавшему самое заумное решение, ему надевали на голову шапочку с пропеллером, а затем раскручивали его и комментировали эту заумь. Негативное внимание со стороны команды заставило людей отойти от усложненных решений и перейти к простой архитектуре и простым решениям. Но все люди разные, и не все в команде с готовностью приняли ХР. Одному человеку не понравился новый стиль работы и тесное сотрудничество, поэтому он покинул проект.
Алистер Коберн. Быстрая разработка программного обеспечения
XP-команды создают код, который легко изменить. Но как они это делают? Ведь никто не собирается создавать код, который изменить трудно.
Многие разработчики – даже очень умные! – стремятся делать наоборот. Они будут настраивать свои команды на создание кода, пригодного для повторного использования, и потратят много времени, пытаясь спроектировать компоненты, которые можно применять многократно. Но планировать повторное использование очень трудно, и совсем непросто довести до конца разработку чрезмерно абстрактного и обобщенного кода. Ведь объем работы, который придется выполнить для создания общей структуры, ровно такой же, какой необходим для выполнения проекта под ключ. Архитектура для многократно используемой библиотеки, созданная сегодня, вскоре превращается в препятствие, которое команда должна обойти или боится трогать.
Многие люди считают, что хрупкий, трудно изменяемый код – это ошибка, типичная для новичков. Но нередко даже лучшие разработчики создают код, который непросто модифицировать. (Неопытные программисты редко создают достаточно большой исходный код, чтобы в нем проявились такие проблемы.) И необязательно написанное ими программное обеспечение будет плохим или неудачно спроектированным. В большинстве случаев это сводится к вопросу, какой код написан: «заумный» или простой.
Для разработчиков (особенно для умных) вполне естественно пытаться решить не только сегодняшние, но и завтрашние проблемы. Большинство из нас присутствовали на сессиях по планированию, которые казались нескончаемыми, потому что каждый думал лишь о своих проблемах и о том, как их решить. И чем крупнее проблема, которая возникла перед командой, тем больше усилий она требует.
Scrum-команды избегают трудностей, связанных с бесконечным планированием, разбивая проект на спринты. Они сосредоточены на сегодняшних задачах и оставляют все остальное на потом, принимая решение о планировании в последний ответственный момент. И когда XP-команды занимаются итерационным планированием, используя квартальные и недельные циклы, они действуют таким же образом.
Принятие решений в последний ответственный момент – это инструмент не только планирования. Он ценен также при проектировании и кодировании. И это главное средство, при помощи которого XP-команды реализуют принцип простоты.
Если вы работали программистом в нескольких командах, то наверняка видели код, который трудно изменить. Создавался он вовсе не с этой целью, а для того, чтобы выполнять что-то полезное. А потом его стали приспосабливать к другим задачам. И после нескольких циклов перепрофилирования код стал сложным. Так как же это произошло?
Код «с душком» и антипаттерны, или как понять, что ты переборщил со сложностью
Простота начинается с понимания того, как не делать слишком много.
Вот пример, как сложность (отсутствие простоты) может повлиять на продукт. Когда один из авторов этой книги учился в колледже, он получил в подарок устройство, сочетавшее в себе функции блендера, миксера и кухонного комбайна. Не все эти функции работали хорошо: он был неплох как блендер, средненький как миксер и совершенно непригодный как кухонный комбайн. Кроме того, в нем проявились проблемы, которые не хочется видеть в подобных приборах. Например, его сменные части было неудобно хранить и практически невозможно отмыть после использования.
Тем не менее он пользовался им десять лет. Но поскольку весь этот сложный набор приспособлений работал не слишком хорошо, приходилось избегать рецептов, для которых требовался кухонный комбайн. Когда же наконец он засунул агрегат на дальнюю полку (потому что рука не поднималась выкинуть «весьма неплохой» электроприбор) и купил самый дешевый кухонный комбайн, он обнаружил, что теперь может готовить по рецептам, которые раньше были недоступны. Оставалось только удивляться, чего он ждал целых десять лет.
Этот прибор был более чем бесполезен. Вместо помощи в приготовлении пищи по разнообразным рецептам, для чего он и был нужен, комбайн только мешал этому. Но его наличие препятствовало покупке нового устройства, поэтому в течение многих лет хозяин избегал рецептов, связанных с использованием кухонного комбайна. И не потому, что у него не было возможности приготовить эти блюда. Просто с прибором было связано слишком много дополнительных проблем. Но долгие годы ему не приходило в голову купить замену, потому что старый был «весьма неплох».
Причина того, что этот прибор был неудобным, заключалась в его сложности. Чтобы соединить в одном приборе три, нужны технические компромиссы, которые привели к тому, что его было сложно использовать (например, было сложно использовать миксерную насадку, потому что она не хотела работать, если не была идеально закреплена). Замена сложного прибора на три простых – дешевые блендер, миксер и кухонный комбайн – сэкономит деньги, они займут меньше места и позволят готовить больше блюд.
Проблемы, подобные этой, объясняют, почему простота – это одна из ценностей ХР, о чем говорилось в . ХР-команды признают, что такая проблема, как сложность, может повлиять на планирование проектов. В этой книге мы уже упоминали, как scrum-команды сталкивались со схожими трудностями.
Например, несложно убедить сотрудников, что для команды, стремящейся быть продуктивной и выполнить проект, не имеет смысла держать людей, сидящих сложа руки. Однако некоторые менеджеры, исповедующие командно-административный стиль руководства, доводят эту идею до крайности: они приносят план проекта, где все 100 % ресурсов уже распределены, и требуют от разработчиков отчета за каждую минуту работы. Постоянный контроль за 100 %-ной загрузкой персонала запланированной работой перегружает управление проектом. Люди должны следить за использованием своего времени и вносить данные в систему контроля (что несложно сделать в теории, но на практике отнимает уйму времени и сил). Менеджерам необходимо составлять, обновлять и пересматривать планы, и невозможно избежать множества совещаний по «решению» проблем, потому что только кажется, что разработчик занимается делом 95 % своего времени.
Получается сложная система управления проектом, но дополнительное усложнение не добавляет ценности в проект. Теперь команда тратит около 20 % своего времени на отслеживание и разговоры о том, на что уходят остальные 80 %, а это увеличивает длительность проекта. Похоже, команда тратит все больше времени на планерки, обсуждая такие вопросы, как «На сколько процентов завершено дело?» и «Можете ли вы оценить, сколько минут потратите на эту задачу?».
XP-команды, так же как scrum-команды, используют итерации для принятия решений по планированию проекта в последний ответственный момент. Такой способ планирования проектов гораздо проще. XP-команды, как правило, не следят постоянно за временем каждого сотрудника, как показано в нашем примере, потому что мониторинг не помогает выполнять проект. Несмотря на благие намерения, собранная информация редко используется для прогнозирования проекта и почти никогда не пересматривается после его завершения. Как уже было сказано, ситуацию ухудшает то, что проекты со временем меняются. Планирование 100 %-ного распределения ресурсов потребует от команды принятия всех решений в начале проекта. Если какое-то из них оказывается неверным (а это обязательно случится, таков нормальный ход проекта), то вся команда должна будет пересмотреть планы, задачи и варианты распределения.
В этом примере есть более значимый урок, помогающий понять ХР. Он связан с признанием паттернов и их применением для улучшения работы.
Если вам доводилось работать в команде, где строгий руководитель командно-административного типа требует от каждого 100 %-ного распределения и собирает бесконечные совещания, чтобы в этом убедиться, требует от каждого постоянно обновлять свой список задач в соответствии с этим надуманным распределением, то, прочитав несколько последних абзацев, вы, возможно, вспомнили эту атмосферу нескончаемых совещаний. Наверняка вы сразу распознали антипаттерн – модель поведения, которую команда демонстрирует в качестве причины, вызывающей проблемы проекта. Опознание антипаттерна в управлении проектом дает возможность обозначить проблему и надежду на отыскание решения, которое поможет упростить эту работу, что позволит команде вернуться к созданию продукта.
XP-команды ищут код «с душком» и исправляют его
Код тоже может содержать антипаттерны, и его распознание – это первый шаг к упрощению вашего кода. Когда антипаттерн относится к структуре кода или архитектуре решения, это называется код «с душком». XP-команды всегда ищут такой код и вырабатывают привычку исправлять его сразу же, как только найдут, не позволяя распространяться на другие модули.
Мы собираемся потратить некоторое время на обсуждение наиболее распространенных вариантов кода «с душком», чтобы вы могли лучше понять образ мышления успешного ХР-разработчика. Этот конкретный список составлен на основании опыта многих разработчиков, обсуждавших проблемы, всплывавшие в их собственных проектах на протяжении ряда лет. Термины «код “с душком”» и «антипаттерн» впервые стали популярны среди разработчиков во второй половине 1990-х годов во многом благодаря сайту WikiWikiWeb (самый первый из Wiki-проектов, созданный автором Аgile-манифеста Уордом Каннингемом). Этот сайт был (а для некоторых остается) одним из самых популярных мест, где разработчики обсуждают проектирование ПО. Чем больше людей собиралось, чтобы поговорить на эту тему, тем чаще они обнаруживали, что существует ряд общих симптомов, с которыми сталкивался каждый из них.
Многие разработчики программного обеспечения (и мы в том числе), впервые сталкиваясь с такими проблемами, реагируют почти на интуитивном уровне.
Это весьма странное ощущение, когда вы мучаетесь непонятным разочарованием и обнаруживаете, что его в точности описывает неизвестный вам человек. И в ходе дальнейшего обсуждения важно иметь в виду, что эти проблемы созданы, признаны и могут быть предотвращены или исправлены людьми. Даже если симптомы носят технический характер, причина в человеческом факторе, поэтому решение должно быть как техническим, так и командно ориентированным.
Когда мы проводим тренинги для разработчиков и говорим о коде «с душком», большинство людей соглашается, что это напоминает «стрельбу дробью». Таким термином описывается ситуация, когда вы хотите сделать небольшое изменение в одной части кода, но обнаруживаете, что оно затрагивает несколько других частей, казалось бы, не связанных с первой. Вы пробуете внести эти изменения и видите, что одно из них требует дополнительной правки в местах, связь которых с первой правкой неочевидна. Если исходный код особенно «плохо пахнет», то нередко программист пытается изменить то, что должно быть простым. Он делает десяток или более переходов в коде и в конце концов сдается, потому что уже не в силах отследить нарастающие каскадом изменения.

 

Рис. 7.1. Успешные XP-разработчики имеют привычку искать и исправлять код «с душком», например очень большие классы или дублированный код. Этим антипаттернам следует придавать структуру отдельных модулей. В этой главе мы будем использовать шестеренки в качестве визуальной метафоры для кода на рисунках

 

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

 

Рис. 7.2. Некоторые примеры кода «с душком» возникают как следствие громоздкой архитектуры системы и сложного взаимодействия модулей

 

Некоторые примеры кода «с душком» появляются тем же способом, что и нормальный код. Когда ваш код включает очень большие классы (или, в случае не объектно ориентированного кода, – громоздкие процедуры, функции, модули и т. д.), его трудно читать и поддерживать. Но часто это признак того, что код пытается выполнять слишком много задач и может быть разделен на более мелкие модули, которые легче понять. В то же время дублируемый код идентичен (или почти идентичен) блоку программы, который встречается в нескольких местах. Это весьма вероятный источник ошибок, особенно если программист вносит изменения в три копии, но забыл про четвертую.
Другой пример кода «с душком» – это неправильная организация взаимодействия отдельных модулей друг с другом. Спагетти-код, или код со сложной и запутанной структурой, – один из самых старых типов кода «с душком», он известен по крайней мере с 1960-х годов. Часто спагетти-код можно распознать по пугающим комментариям других разработчиков, которые ранее безрезультатно пытались распутать его. А другая разновидность – лазанья-код – может оказаться более коварной проблемой. Современная архитектура программного обеспечения, как правило, делит код на слои. Каждый из них имеет определенную цель или выполняет определенную роль, и эти слои составляют общую архитектуру. Однако когда слоев слишком много и шаблоны, по которым их писали, оказались несогласованными, становится трудно понять, что должен делать каждый слой. Эта ситуация может усугубляться протечками между слоями, где код, типы данных или идеи, которые должны находиться в одном слое, просачиваются в соседние.
Хуки, крайние случаи и код, делающий слишком много
Приведенные примеры кода «с душком» обусловлены его структурой. Но бывают также проблемы, связанные с тем, что делает код, то есть с его функциональностью. И успешные ХР-разработчики понимают, что они должны заботиться о поведении кода не меньше, чем о его структуре.
Приведем пример. Команда будет прогнозировать способ использования модуля кода (например, класса Java) в будущем и добавит некий хук, или заполнитель, который впоследствии будет заменен кодом. Хук кажется «бесплатным», но на самом деле имеет цену: он связывает команду принятым сегодня решением, которое можно было бы отложить на будущее. Когда наконец приходит время для использования хука, команда глубже понимает проблему и он должен быть другим. Команда приходит в замешательство, обнаружив, что ее предположения о том, как будет использован хук, привели к необходимости создать еще одну часть кода, которая будет обходить этот хук. Поэтому его стало гораздо труднее изменить (несмотря на то, что он пуст!) – ведь он уже используется в другом месте кода. Программист, привыкший добавлять слишком много хуков, забывает, где они расположены. Он будет постоянно сталкиваться с неприятностями при попытке использовать код, написанный несколько недель назад. Ведь окажется, что нужный код так и не был написан, а вместо него стоит комментарий со словами «надо сделать».
Это антипаттерн: добавление такого количества хуков, что становится трудно точно отследить, что именно делает код.
Другой антипаттерн, создающий сложности в понимании кода, – это зацикленность на исключениях. Исключение – редко встречающаяся ситуация, происходящая при определенном наборе обстоятельств. Например, программа, которая загружает данные из файла, должна обработать случай, когда файл не найден. Ей может также понадобиться отреагировать на ситуацию, когда не удается найти папку, содержащую файл, вероятно, реагируя иначе, чем в первом случае. Возможно также, что файл существует, но не может быть прочитан или его удаляют во время чтения либо данные в нем имеют неверную кодировку. Хороший программист придумает еще множество возможных проблем в такой простой ситуации, как чтение данных из файла. Ну и на чем ему остановиться?
Многие вязнут в обработке слишком большого числа исключений. Но она действительно необходима, и многие ситуации требуют обработки нескольких различных вариантов. Но чем больше обрабатывается вариантов исключений, тем меньше польза для проекта от добавления еще одного. Некоторые программисты попадают в замкнутый круг, пытаясь написать «непрошибаемый» код и тратя на обработку исключений столько же усилий, сколько и на основную часть кода. В этот момент исключения становятся сходными с избыточным планированием и начинают отвлекать усилия от основной работы. Код для обработки ошибок срабатывает редко. Если программа выглядит как запутанный клубок исключений, то ее труднее понять и изменить.
Хорошие разработчики, как правило, относятся к тому типу людей, которые зацикливаются на деталях, и исключения – это как раз такая деталь. Именно глубокий ум может превратить программиста в человека, одержимого исключениями. Когда такое случается, на командных совещаниях начинается бесконечное обсуждение исключений для особых ситуаций, в ходе которого каждый участник неожиданно приобретает твердое убеждение, что значимое для него исключение обязательно должно быть обработано.
Если разработчики чрезмерно увлечены планированием исключений или добавляют слишком много хуков, это можно считать умничаньем. Вместо создания простого, легко изменяемого кода они размышляют о написании усложненного, чересчур абстрактного кода или занимаются решением завтрашних, а не сегодняшних задач.
Это подводит нас к так называемой платформенной ловушке – антипаттерну, вытекающему из умствования разработчиков. Платформенная ловушка – это ситуация, когда разработчику нужно решить некую проблему или выполнить задание. Но вместо того чтобы написать код для решения именно этой задачи, он создает более обширную платформу, которая может быть использована в дальнейшем для работы в схожих ситуациях.

 

Рис. 7.3. Блестящий веб-комикс xkcd показывает, что происходит, когда разработчики попадают в платформенную ловушку

 

Рон Джеффрис, партнер Кента Бека по созданию ХР, описал, как избежать платформенной ловушки. «Реализуйте то, в чем вы действительно нуждаетесь в данный момент, и не стремитесь предугадывать, что вам может понадобиться в будущем». Некоторые XP-команды любят использовать аббревиатуру YAGNI (You Ain’t Gonna Need It – «вам это не понадобится»), если речь заходит о таких ситуациях. Пытаясь предугадать будущие потребности и создавая дополнительный код, чтобы их удовлетворить, вы легко попадаете в платформенную ловушку.
Вместо того чтобы сосредоточиться на текущей задаче, чересчур умные разработчики замахиваются на более глобальные цели. Они размышляют примерно так: «Я могу написать это простое решение, но гораздо лучше сделать код, автоматизирующий такую работу, чтобы никому больше не пришлось ею заниматься». У программиста, начавшего писать веб-страницу, в результате получается конструктор для их создания. Попытка решить конкретную проблему производительности приводит к появлению большого кэша общего назначения. Простая программа для загрузки файлов по расписанию непонятным образом приобретает скриптовый движок.
Нетрудно понять, почему разработчики идут по этому пути. Они думают так: «Если бы кто-то другой создал платформу для работы, которую я сейчас выполняю, то я бы просто ее применил. Так почему бы не потратить немного времени на решение проблемы в общем виде?» Это очень благородно со стороны разработчиков и объясняет, почему так много команд попадают в платформенную ловушку.
Постойте, а что не так с повторно используемыми платформами?
Все нормально, и, конечно, в XP нет ничего, что исключает использование или разработку таких платформ. Одна из наших наиболее популярных книг Head First CM учит программистов использовать. NET Framework, технологию Microsoft, для создания Windows-приложений. Существуют отличные готовые платформы для разработки веб-приложений, рендеринга 3D-графики, создания сетевых сервисов и т. д.
Это не значит, что у вашего проекта должна быть установка на создание сетевого сервиса.
Поговорим еще немного о возможности повторного использования, потому что платформенная ловушка – это наше название для антипаттерна, связанного с созданием повторно используемого кода, чего XP-команды учатся избегать. Многократно используемый код (код, который носит достаточно общий характер и может применяться в разных частях системы) – это цель многих разработчиков. И в этом есть определенный смысл. Кнопки в диалоговых окнах в текстовом процессоре похожи друг на друга и работают примерно одинаково. Было бы странно, если бы команда, создающая текстовый редактор, писала отдельный код для каждой кнопки. Программисты напишут код кнопки один раз и будут повторно использовать его по мере необходимости. Но кнопки в диалоговых окнах текстового редактора работают и выглядят так же, как в браузере и других приложениях. Так что код для этих кнопок (вероятно) находится за пределами любой из этих программ – ваша операционная система предоставляет библиотеку для основных кнопок. Код кнопки был написан однажды и повторно используется тысячи раз. Это явно экономит время.
Программисты редко создают что-либо с нуля. В их распоряжении библиотеки, применяемые для чтения и записи файлов, доступа к сетевым ресурсам, графике и т. д. Это основной факт программирования: хороший разработчик, сталкиваясь с незнакомой проблемой, прежде всего ищет решение в веб-библиотеке. Поэтому, решив проблему, с которой могут столкнуться другие, он часто старается поделиться вариантом кода. Это продуктивный способ создавать программное обеспечение.
В чем разница между библиотекой и платформой?
Вы знаете, что можете использовать библиотеку как независимую часть своего проекта.
Разница в том, что в библиотеке хранится код, разделенный на небольшие компоненты, которые можно применять повторно. Если цель заключается в создании простого кода, то каждый компонент должен делать только одну функцию. Компонент, выполняющий несколько функций, следует разделить на меньшие, более независимые модули. Это так называемое разделение ответственности; эффективные ХР-разработчики признают, что это важный элемент обеспечения простоты кода.
А платформа – это объединение множества мелких, повторно используемых частей в одну большую систему. Изучение языка C#, например, помимо его синтаксиса означает также освоение. NET Framework.
Эта платформа включает в себя библиотеки для доступа к файлам, выполнения математических расчетов, подключения к сетям и многого другого (в том числе использования кнопок). Когда вы начинаете создавать свою программу при помощи C# и. NET, вы бесплатно получаете все упомянутые выше модули, потому что они часть платформы. NET. Из нее невозможно выделить нужный кусочек кода. И действительно, не имеет смысла пытаться использовать одну часть платформы. NET в программе, которая написана без ее использования. Как и в большинстве платформ, в ней многие части были объединены в большую единую систему.
Платформы гораздо сложнее библиотек. Команда, пытающаяся создать платформу, когда для данной задачи больше подходит библиотека, вынуждена использовать чрезмерно усложненную архитектуру. Часто эта ошибка встречается из-за того, что программисты видят, как другие платформы сберегают им массу времени, и хотят, чтобы их код делал то же самое.
Недостаток такого подхода в том, что, желая получить все эти компоненты даром, вы должны использовать платформу целиком. Иногда это заставляет вас взглянуть на проблему по-новому. Разработчик. NET действительно будет воспринимать проблему иначе, чем Java-разработчик (разница не всегда велика, потому что у этих платформ много общих концепций), и абсолютно по-другому, чем программист на С++, Python, Perl или Lisp. Так происходит, потому что, когда у вас есть набор инструментов для устранения проблем, вы ищете решение, отталкиваясь от этих инструментов. Это только примеры языков и платформ (думая о разработке ПО на Java, Python или Perl, вы наверняка будете учитывать имеющиеся в этих языках стандартные библиотеки), поэтому в них не принимаются во внимание различные ограничения, с которыми вы столкнетесь, решая свои проблемы.

 

Рис. 7.4. Создание сложных платформ для решения простых задач иногда воспринимается как дело, которым надо заниматься именно сейчас (источник: xkcd)

 

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

 

Приведем типичный пример мышления, ориентированного на платформы. Команды используют скрипты для автоматической сборки программного обеспечения. (В мы узнали, что в XP-командах эти скрипты выполняются менее чем за 10 минут.) Для создания скриптов существует немало инструментов, и многие из них включают в себя скриптовые языки. Но для разработчика с платформенным мышлением, работающего над несколькими проектами, недостаточно просто написать отдельный скрипт для каждого проекта. Похоже, в этих скриптах дублируется слишком много кода (часто так оно и есть), поэтому такой программист напишет единую сборочную платформу для всех проектов. («Если вы используете мою платформу, то вам не придется писать сборочный скрипт. Вы получите его готовым!) Поэтому вместо недлинных скриптов для каждого проекта создается большая платформа, которая требует отдельной поддержки. Этот разработчик пошел на сделку: он предотвратил повтор нескольких десятков строк сборочного скрипта, заменив их на платформу, которая содержит сотни, даже тысячи строк кода. Когда во время сборки что-то пойдет не так (по закону Мерфи это происходит в ночь перед выпуском), вместо устранения небольшой неполадки в сборочном скрипте разработчику придется искать ошибку в большой платформе. Это нельзя назвать простым решением.
Объединение значительного числа функций в большой платформе для решения определенной проблемы может действительно дать результат. Но если проблема меняется, то внести изменения в платформу труднее.
Иными словами, объединяя множество разных частей в большие платформы, члены команды думают, что экономят время, но на самом деле они лишь ограничивают способность реагировать на новые запросы. Мы называем это явление платформенной ловушкой и можем использовать как пример для изучения простоты и ее влияния на проект. Причина, по которой нам нравится приводить в качестве примера такую ловушку, заключается в том, что она отражает важный аспект мышления, который не всегда совместим с XP: некоторые разработчики предпочитают объединять все функции в один большой блок, а не разделять их на множество мелких модулей.
Код «с душком» увеличивает сложность
Мы только что описали несколько разновидностей кодов «с душком», которых ХР-команды обычно стараются избегать. Все эти коды объединяет одна черта: они увеличивают сложность проектов. Верно и обратное: если вы обнаружили, что вам необходимо запоминать, как инициализировать объект, или трудно удерживать в голове каскад вынужденных изменений, или вы подолгу пытаетесь разобраться в спагетти-коде, значит, исходный код вашего проекта излишне усложнен. Именно поэтому XP-команды стремятся как можно раньше найти и исправить код «с душком».
Речь идет не только о коде «с душком», который, возможно, не такой уж частый гость в ваших проектах. Тем не менее мы выбрали этот пример, потому что за долгие годы общения с разработчиками обнаружили, что почти все сталкиваются с похожими проблемами в своем коде. Они возникают неслучайно и не из-за низкой квалификации разработчиков или их лени. Это является результатом плохих привычек программистов, особенно когда они попадают в ситуацию цейтнота или вынуждены обходить ограничения (в том числе те, что заложили в код в начале проекта).
Так что же вы делаете, когда в вашем проекте появляется код «с душком»? Можно ли это предотвратить?

 

Ключевые моменты
ХР-команды выявляют код «с душком» (или антипаттерны), чтобы избежать сложности и сохранить простоту архитектуры.
Код «с душком», такой как сырой код и очень большие классы, помогает командам обнаружить отдельные модули, которые можно упростить.
Такой код «с душком», как лазанья-код, помогает им искать проблемы в более крупных конструкциях.
Особенно неприятно, когда код «с душком» вызывает эффект «стрельбы дробью», то есть разработчик пытается исправить проблему, но обнаруживает, что внесенные изменения требуют целой цепочки правок в других частях кода.
Команды, чрезмерно увлекающиеся планированием в стремлении предусмотреть все особые случаи, добавляют слишком много хуков или создают большие платформы для решения отдельных проблем, что приводит к усложнению кода.
Даже высококвалифицированные специалисты, подверженные плохим привычкам, могут столкнуться с этими проблемами.
Назад: Акт IV. Работа в сверхурочное время, часть 2: снова сверхурочные
Дальше: Принимать решения по коду и проекту в последний ответственный момент