возникающей архитектурой.

Системы, созданные с использованием возникающей архитектуры, практически всегда состоят из маленьких, независимых, несвязанных модулей (подобных утилитам Unix или муравьям). Эти части объединяются для выполнения сложных задач, и поведение системы зависит как от взаимодействия между этими модулями, так и от них самих.

Глубокая иерархия модулей, вызывающих один другой, применяется редко. Вместо этого система будет использовать сообщения, очереди или другие способы коммуникации модулей, не требующие централизованного управления. Утилиты Unix – хороший пример такой организации работы[71]. Входной сигнал передается от одной утилиты к другой, что облегчает их объединение в цепочку. Это приводит к очень простому, последовательному использованию: вызывается первая утилита, потом вторая, затем третья. Можно создать и более сложное взаимодействие между инструментами, но это приводит к простой, неглубокой структуре вызовов (в отличие от глубокой, вложенной иерархии вызовов со слоями модулей).

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

Людям, потратившим годы на создание набора утилит Unix, знакомо это чувство возникающего поведения. Можно получить первое поверхностное представление о возникающем поведении, наблюдая за тем, как сочетаются утилиты в приведенном примере с адресной книгой: cut умеет только извлекать символы из строки, а grep – искать соответствие шаблонам, но их сочетание обеспечивает обработку адресов без специальной команды, которая пояснит системе, что такое адрес и как его обработать.

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

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

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

Новая архитектура возникает, когда команда обнаруживает изменения, которые необходимо сделать. Чтобы добавить новое поведение в систему или переменить способ ее работы, команда должна изменить отдельные модули или способ их взаимодействия. Но поскольку каждый модуль несвязан и взаимодействия между ними просты, эти изменения, как правило, не носят каскадного характера по всей системе. Если встречается код «с душком» (скажем, программист обнаруживает, что занимается «стрельбой дробью», продирается через спагетти-код или сырые объекты), то это серьезное предупреждение, что во время работы были допущены ненужные усложнения. И разработчик знает (а что еще важнее – чувствует): стоит потратить время на рефакторинг, чтобы разделить код на более простые модули.

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

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

Другими словами, команды сохраняют код простым, что позволяет им принимать изменения.

В этом суть ХР.

<< | >>
Источник: Эндрю Стеллман, Дженнифер Грин. Постигая Agile. Ценности, принципы, методологии. 2015

Еще по теме возникающей архитектурой.:

  1. Архитектура службы конкурентной разведки
  2. 2. Часто возникающие проблемы
  3. РИСКИ, ВОЗНИКАЮЩИЕ В СВОПАХ
  4. Модификации возникают из единообразия
  5. Спонтанно возникающие формы
  6. 2. Часто возникающие проблемы
  7. Этапы восприятия и возникающие на них помехи
  8. Продуктивность не возникает сама по себе
  9. возникает рыночная «щель» в предложении
  10. Некоторые часто возникающие на практике проблемы
  11. Иногда одни и те же проблемы возникают постоянно
  12. Разницы, возникающие при осуществлении финансовых вложений
  13. Когда возникает необходимость ведения раздельного учета
  14. Особенности трансформации возникающих разниц по нормируемымрасходам в бухгалтерском и налоговом учете
  15. 10. Творчество возникает тогда, когда для него есть место
  16. Разницы, возникающие между бухгалтерским и налоговым учетомамортизируемого имущества, порядок их погашения