Постигая Agile — страница 54 из 89

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

Программисты редко создают что-либо с нуля. В их распоряжении библиотеки, применяемые для чтения и записи файлов, доступа к сетевым ресурсам, графике и т. д. Это основной факт программирования: хороший разработчик, сталкиваясь с незнакомой проблемой, прежде всего ищет решение в веб-библиотеке. Поэтому, решив проблему, с которой могут столкнуться другие, он часто старается поделиться вариантом кода[62]. Это продуктивный способ создавать программное обеспечение.

В чем разница между библиотекой и платформой?

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

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

А платформа – это объединение множества мелких, повторно используемых частей в одну большую систему. Изучение языка C#, например, помимо его синтаксиса означает также освоение. NET Framework.

Эта платформа включает в себя библиотеки для доступа к файлам, выполнения математических расчетов, подключения к сетям и многого другого (в том числе использования кнопок). Когда вы начинаете создавать свою программу при помощи C# и. NET, вы бесплатно получаете все упомянутые выше модули, потому что они часть платформы. NET. Из нее невозможно выделить нужный кусочек кода. И действительно, не имеет смысла пытаться использовать одну часть платформы. NET в программе, которая написана без ее использования. Как и в большинстве платформ, в ней многие части были объединены в большую единую систему.

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

Недостаток такого подхода в том, что, желая получить все эти компоненты даром, вы должны использовать платформу целиком. Иногда это заставляет вас взглянуть на проблему по-новому. Разработчик. NET действительно будет воспринимать проблему иначе, чем Java-разработчик (разница не всегда велика, потому что у этих платформ много общих концепций), и абсолютно по-другому, чем программист на С++, Python, Perl или Lisp. Так происходит, потому что, когда у вас есть набор инструментов для устранения проблем, вы ищете решение, отталкиваясь от этих инструментов. Это только примеры языков и платформ (думая о разработке ПО на Java, Python или Perl, вы наверняка будете учитывать имеющиеся в этих языках стандартные библиотеки), поэтому в них не принимаются во внимание различные ограничения, с которыми вы столкнетесь, решая свои проблемы.


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


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


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

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

Иными словами, объединяя множество разных частей в большие платформы, члены команды думают, что экономят время, но на самом деле они лишь ограничивают способность реагировать на новые запросы. Мы называем это явление платформенной ловушкой и можем использовать как пример для изучения простоты и ее влияния на проект. Причина, по которой нам нравится приводить в качестве примера такую ловушку, заключается в том, что она отражает важный аспект мышления, который не всегда совместим с XP: некоторые разработчики предпочитают объединять все функции в один большой блок, а не разделять их на множество мелких модулей.

Код «с душком» увеличивает сложность

Мы только что описали несколько разновидностей кодов «с душком», которых ХР-команды обычно стараются избегать. Все эти коды объединяет одна черта: они увеличивают сложность проектов. Верно и обратное: если вы обнаружили, что вам необходимо запоминать, как инициализировать объект, или трудно удерживать в голове каскад вынужденных изменений, или вы подолгу пытаетесь разобраться в спагетти-коде, значит, исходный код вашего проекта излишне усложнен. Именно поэтому XP-команды стремятся как можно раньше найти и исправить код «с душком».

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

Так что же вы делаете, когда в вашем проекте появляется код «с душком»? Можно ли это предотвратить?


Ключевые моменты

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

Код «с душком», такой как сырой код и очень большие классы, помогает командам обнаружить отдельные модули, которые можно упростить.

Такой код «с душком», как лазанья-код, помогает им искать проблемы в более крупных конструкциях.

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

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

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

Принимать решения по коду и проекту в последний ответственный момент

Переход к проектированию в XP-стиле – это смещение дат принятия проектных решений. Проектирование откладывается до тех пор, пока не появится возможность использовать накопленный опыт и сразу же внедрять принятые решения. Это дает возможность команде:


• разворачивать программное обеспечение как можно раньше;

• принимать решения с уверенностью;

• избегать последствий плохих решений;

• сохранять темпы разработки на первоначальном уровне, несмотря на изменения.


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

Кент Бек. Extreme Programming Explained: Embrace Change

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