Код «с душком» и рефакторинг помогут создать несвязанный код. Вернемся к примеру рефакторинга с кодом улья, где мы извлекли два метода из блока кода C# для перемещения пчел между полем и ульем. Мы увидели, что эти два метода могут повторно использоваться в другой части программы, которая должна перемещать пчел таким же образом. Но что если эти методы – часть более крупного модуля, который нуждается в большой инициализации? Программист с хорошими навыками, попытавшись повторно использовать эти простые методы, почувствует непродуманный код и проведет рефакторинг, чтобы удалить дополнительную инициализацию. Теперь этот код можно применить в двух различных частях программы, и для этого не нужно «знать», как его вызывать, потому что он отделен от тех частей кода, которые к нему обращаются. И если необходимо, чтобы он был вызван из третьей части кода, то он будет отделен и от этой части.
Систему легче поддерживать, если она собрана из небольших независимых модулей, то есть каждая часть кода отделена от любой другой, насколько это возможно (степень этой зависимости может быть удивительной), так что между ними существует очень мало зависимостей. Это главный принцип создания программы, которая может быть изменена без серьезной доработки. Если ваша архитектура не отягощена лишними связями, то вам редко придется прибегать к «стрельбе дробью» или производить целую череду взаимосвязанных изменений. И когда вы начнете так поступать и выработаете в себе привычку не откладывать рефакторинг на завтра, чтобы удалить эти сцепления, код будет становиться все лучше и лучше: каждый модуль станет выполнять только одну задачу и окажется отделен от посторонних модулей.
Инкрементальная архитектура и целостные XP-практики
В главе 6 мы говорили о 10 из 13 основных XP-практик, разделив их на категории: программирование, интеграция, планирование и командные практики. Существуют еще три основные XP-практики, и мы придумали для них отдельную категорию:
Первая целостная ХР-практика, о которой мы будем говорить, – это инкрементальная архитектура. Она самая трудная для понимания. В этой главе мы постараемся помочь вам понять основы этой практики и то, как она влияет на проект и команду в целом.
Вы можете найти замечательные примеры инкрементальной архитектуры во многих зрелых, качественных проектах с открытым исходным кодом, таких как Linux, Apache HTTP Server и Firefox. Эти проекты создаются вокруг стабильного ядра. Разработчики используют архитектуру, основанную на плагинах (или других способах отделения кода от ядра), чтобы создавать дополнительные функции, и только самые повторяющиеся, наиболее стабильные из них встраиваются в ядро. Такая архитектура приводит к весьма слабо связанному коду, и программисты, работающие над этими проектами, взяли за правило часто делать рефакторинг, писать много тестов и выполнять непрерывную интеграцию. (Следует отметить, что многие практики, включенные в XP, возникли или были отточены разработчиками, участвующими в проектах с открытым исходным кодом.)
Каждый из таких проектов создан программистами, добавлявшими отдельные модули, работающие независимо друг от друга и созданные специально для взаимодействия с ядром проекта. Создается впечатление, что исходный код проекта постепенно вырастает из этого ядра. Любой разработчик может добавить свои собственные модули независимо от остальной команды и рассчитывать на то, что все пишут почти полностью разъединенный код, поэтому риск столкновения новых модулей со старыми невелик. Однако работа ведется не в вакууме, и члены команды хорошо осведомлены об этом. Все дополнения происходят в том же исходном коде, где эти команды проводят автоматизированную или ручную непрерывную интеграцию. (Некоторые непрерывные интеграции и серверы сборки, доступные сегодня, возникли в ходе этих проектов.) Кроме того, каждый разработчик старается избежать кода «с душком» и антипаттернов и чувствует большую ответственность за их исправление, если они будут выявлены.