По мере роста организаций одной из крупнейших задач становится поддержание эффективной коммуникации и координации между людьми и командами. Когда люди и команды находятся на разных этажах, в различных зданиях или даже часовых поясах, создать и поддержать общее понимание и взаимное доверие сложно, и это препятствие для эффективной совместной деятельности. Сотрудничеству также мешают ситуации, когда основные механизмы коммуникации — задания на работу и запросы на изменения. Еще хуже, когда команды разделены установленными в договоре границами, как в случае выполнения заданий аутсорсинговыми командами.
Как мы видели на примере Sprouter в компании Etsy, описанном в начале этой главы, способ формирования команд может давать плохие результаты — таков побочный эффект закона Конвея. В число таких способов входит разделение групп по функциям (например, размещение разработчиков и тестировщиков в разных местах или полная передача тестирования на аутсорсинг) либо по слоям архитектуры (например, приложения, базы данных).
Такие конфигурации требуют значительных коммуникаций и координации между группами, но по-прежнему приводят к большим объемам переделок, разногласиям в спецификациях, неудовлетворительной передаче работы из одних отделов в другие и к тому, что специалисты простаивают, ожидая завершения смежниками их части проекта.
В идеале архитектура программного обеспечения должна позволить небольшим командам действовать независимо, продуктивно и быть достаточно отделенными друг от друга, так чтобы работа могла быть сделана без чрезмерных или вовсе ненужных коммуникаций и координации.
Когда мы имеем сильно связанную архитектуру, небольшие изменения могут привести к крупномасштабным сбоям. В результате все, кто имеет дело с какой-то одной частью системы, должны постоянно координировать с другими отделами все задачи, влияющие на другие части системы, и эта координация осуществляется через сложные бюрократические процедуры управления изменениями.
Кроме того, проверка слаженности системы требует учета изменений, внесенных сотнями или даже тысячами других разработчиков, а они могут, в свою очередь, зависеть от десятков, сотен и тысяч взаимосвязанных систем. Тестирование осуществляется в условиях ограниченной интеграции тестовых сред, часто требующих недель на настройку. В результате не только требуется много времени на внедрение изменений (обычно недели или месяцы), но также низкими оказываются производительность труда разработчиков и результаты развертывания.
Напротив, если архитектура позволяет небольшим командам разработчиков реализовывать, тестировать и развертывать код в производство независимо, быстро и безопасно, мы можем увеличить и поддерживать на высоком уровне продуктивность разработчиков и улучшить результаты развертывания. Такими характеристиками обладает
Слабосвязанная архитектура означает, что сервисы можно обновлять в производстве независимо друг от друга, без необходимости обновления других сервисов. Сервисы должны быть отделены от других сервисов и, что не менее важно, от общих баз данных (хотя они могут совместно использовать
Ограниченные контексты описаны в книге Эрика Эванса «Предметно-ориентированное проектирование (DDD). Структуризация сложных программных систем»[54]. Идея в том, что разработчики должны быть в состоянии понять и обновить код сервиса, не зная ничего об устройстве других сервисов, вместе с которыми он функционирует. Сервисы взаимодействуют друг с другом только через API и не имеют общих структур данных, схем баз данных или других внутренних представлений объектов. Ограниченные контексты обеспечивают разграничения между сервисами и имеют хорошо определенные интерфейсы, что, ко всему прочему, упрощает тестирование.
Рэнди Шуп, бывший технический директор Google App Engine, отметил: «Организации с этими типами сервис-ориентированной архитектуры, такие как Google и Amazon, невероятно гибки и масштабируемы. Эти организации имеют десятки тысяч разработчиков, небольшие группы которых все еще способны быть невероятно продуктивными».