Архитектура и Проектирование

Существует 10 типа людей: кто понимает двоичный формат и кто нет.
-- неизвестный

В ландшафтном дизайне существует эволюционная методика проектирования с использованием “протоптанных тропинок”.

desire_line.jpg
"Протоптанные тропинки"

Проблема: Где проложить дорожки для прогулок в новом парке? Какими широкими они должны быть?

Решение: Подождите год и наблюдайте за тем, как люди естественным образом гуляют там, где им удобно. Создавайте дорожки вдоль этих “протоптанных тропинок” такими широкими, насколько это нужно. Дизайн “вытягивается” спросом, а не задаётся произвольно.

Несмотря на сложность применения в разработке продуктов, описанный выше подход является одним из источников вдохновения при бережливой или гибкой разработке - что-то вроде эмергентного проектирования (emergent design)1.

Наверное есть незанятая ниша для отличной толстой книги по “Масштабному гибкому проектированию” - так вот это не она. Это не трактат по техническому проектированию. Статья предлагает несколько поведенческих советов, относящихся к гибким проектированию и масштабной разработке, с несколькими техническими советами, о которых стоит упомянуть (некоторые из которых похожи на “протоптанные тропинки”). Некоторые советы отражают принципы бережливой разработки программного обеспечения lean software principles, такие как “решить в последний ответственный момент” (decide at the last responsible moment). Некоторые отражают принципы Манифеста Гибкой Разработки ПО, такие как “Непосредственное общение является наиболее практичным и эффективным способом обмена информацией как с самой командой, так и внутри команды”. Также многие рекомендации поддерживают девятый принцип этого манифеста: “Постоянное внимание к техническому совершенству и качеству проектирования повышает гибкость проекта”.

Размышления о проектировании

“Выращивание”, а не “строительство” - Создавайте культуру живого, растущего дизайна системы

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

Использование слова “архитектура” в повседневной речи при разработке программного обеспечения происходит минимум в двух значениях:

  • (сущ.) крупномасштабные статические и динамические структуры и шаблоны
    • также необходимая архитектура (предполагаемая, желаемая) по сравнению с текущей - которая может быть не достижима
  • (гл.) создание и определение предполагаемой архитектуры, как в “подготовка архитектуры” или “когда вы будете готовить архитектуру?”
    • выполняется один раз в начале проекта, зачастую только на бумаге
    • пересекается с анализом требований

Термин был заимствован у “классических” архитекторов, которые проектируют материальные объекты: здания и сооружения. Такая аналогия3 становится слабо применимой, обладая интересными побочными эффектами для разработки программного обеспечения. Здания являются “твёрдыми” (hard), и поэтому в этой области проектирование архитектуры выполняется только один раз перед началом строительства - по крайней мере, в наши дни - и затем и архитектура и здания почти не меняются. Отметим также, что архитекторы и конечные строители - разные группы людей. Но программное обеспечение - это не здание, программное обеспечение “мягкое” (software - soft), а программирование - это не процесс строительства; “Архитектура программного обеспечения” - это всего лишь ещё одна несовершенная аналогия из большого списка возможных метафор.

Какие ещё метафоры применимы? Можно процитировать статью Джека Ривза “What is Software Design?”

… Единственная документация, которая на самом деле описывает достоверно дизайн системы, это её исходный код

Я (Крэг Ларман) написал книгу по анализу программного обеспечения, проектированию, моделированию, шаблонам и архитектуре. Я указал этот факт здесь не для того, чтобы себя похвалить (у меня “средний” уровень навыков в разработке ПО) или назвать себя “хакером” (в плохом смысле этого слова). Однако я с 1970-х годов работал в качестве программиста, и я признаю, что диаграммы и документы - это не настоящий дизайн, а скорее настоящий дизайн - это исходный код. ещё раз повторю: “… единственная документация по программному обеспечению, которая на самом деле соответствует критериям технического дизайна - это исходный код”.

Исходный код (на языке C, C ++, …) является настоящим “проектным планом”. И только в контексте программного обеспечения Сборка (“билд”, Build) практически бесплатна и мгновенна4. Следовательно, многие не видят его таким, какой он есть: Сборка - это этап компиляции и компоновки. Не случайно, что в инструментах разработки пункт меню для запуска компиляции называется Сборка.

build_menu.png

Сценарий: Предположим, что в первые дни существования Продукта Х существовали высокоуровневые проектные документы для крупных элементов системы, идиом и взаимодействий в рамках предполагаемой архитектуры, и предположим также, что реальный дизайн (исходный код) хорошо отражает эти требования. Прошло семь лет и все программисты, которые начинали разработку, больше не работают, а были наняты 300 новых не очень квалифицированных разработчиков, которые на самом деле не знают или не думают о первоначальных концепциях высокоуровневого дизайна. Представьте, что они добавили 9,5 миллионов строк кода (9,5 MLOC), и предположим, что это 95 процентов всего кода - и тогда это источник путаницы.

Где настоящая архитектура - хорошая или плохая, намеренная или случайная? В документах, поддерживаемых (или нет) группой архитектуры, или в 10 миллионах строк (10 MLOC) C/C++ кода в десятках тысяч файлов? Очевидно, что последнее - исходный код является реальным дизайном, и только он отражает истинный дизайн или архитектуру в масштабе. Архитектура - это то, что есть, а не то, что кому-то хочется. “Архитектура” в программной системе не обязательно является хорошей или намеренной.

Первое наблюдение - Сумма всего исходного кода - это настоящий план проекта или архитектура.

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

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

Аналогия с растениями, парками и садоводством является полезной. Например, в английском языке термин ландшафтная архитектура употребляется, и как нечто статическое и как действие - и это нормально умело продумать и спроектировать общий план большого сада или парка заранее. Но этот план не остаётся таким навсегда. Растения растут, парк меняется со временем, и очевидно, что фактическая ландшафтная архитектура быстро превратится в джунгли из сорняков без постоянного присмотра и “подрезки” со стороны экспертов-садоводов, которые помнят как о первоначальном, так и о эволюционном видении парка. У нас есть друг, который работает ландшафтным архитектором, его специализация - поля для гольфа. Он сам лично наблюдает свой проект во время его создания, прогулок и игры в гольф уже после его сдачи - всегда на связи с реальностью с тем, что происходит.

Этот переход от метафоры архитектуры ПО к её выращиванию, как живой, повлиял на многих людей, размышляющих об успешной разработке. Например, Фредерик Брукс в своей известной статье Нет серебряной пули делится своим пониманием:

Метафора “строительства” исчерпала свою полезность… Если, как я полагаю, концептуальные структуры, которые мы строим сегодня, слишком сложны, чтобы их можно было точно определить заранее, и слишком сложны, чтобы их можно было безошибочно построить, тогда мы должны использовать радикально иной подход… Секрет в том, что это выращено, а не построено… Харлан Миллс предложил, чтобы любая программная система росла путём инкрементальной разработки… Ничто за последнее десятилетие так радикально не изменило мою собственную практику или её эффективность…

Третье наблюдение - Настоящую живую архитектуру нужно выращивать каждый день актами написания кода экспертами-разработчиками.

Четвёртое наблюдение - Архитектор программного обеспечения, который не имеет отношения к меняющемуся исходному коду продукта, оторван от реальности.

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

Какое это имеет отношение к масштабированию разработки и гибкости?

В небольшой продуктовой группе, состоящей из 20 человек, люди хорошо понимают вышесказанное, и редко существует узаконенная ложная дихотомия или разделение между архитектурой и программированием. Кроме того, если есть официальный “архитектор”, то этот человек, как правило, тоже пишет код. Но в большой продуктовой группе с 600-ми сотрудниками в громадной компании существует распространённая ошибка ментальной модели: проектирование или архитектура структурно отделены от кода и процесса программирования. Следовательно, нередко можно найти отдельную группу архитектуры и/или системной инженерии, организованную ими “архитектурную” ступеньку (до программирования), и её члены не являются разработчиками-практиками или, по крайней мере, не самыми лучшими экспертами в написании кода мирового уровня.

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

Какие могут быть последствия? В большой продуктовой группе с (1) ментальной моделью, согласно которой архитектура и строительства ПО, как материальных зданий, считается хорошей метафорой; (2) отсутствием понимания того, что истинная архитектура находится в исходном коде; (3) архитекторами-астронавтами, которые не должны писать код, происходит деградация архитектуры с
течением времени. Почему? Динамика такой системы показана на диаграмме причинно-следственных циклов (casual-loop diagram, CLD) ниже. Обратите внимание на несколько положительных петель обратной связи, которые могут усиливать деградацию или улучшение со временем.

dynamics related to architecting metaphoor
диаграмме причинно-следственных циклов с некоторой динамикой, относящейся к метафоре ‘архитектуры’.

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

Если системная динамика увеличивает влияние PowerPoint-архитекторов, то в результате они оказывают влияние, уменьшающееся со временем, так как они не связаны с реальным кодом. В конце концов они теряют связь и в конечном итоге пишут документы друг для друга или для заинтересованных сторон. Настоящие “случайные” архитекторы (программисты) в основном их игнорируют.

Однажды у нас был разговор с опытным программистом, который написал драйвера для сетевых процессоров, которые являются частью очень большого продукта. Он был обеспокоен тем, что архитекторы из башни из слоновой кости, расположенные на два этажа выше, буквально в другой башне, выбрали новый сетевой процессор, который потребует полного переписывания всех драйверов - по оценкам, это будет как минимум девять месяцев работы по написанию кода. И это даже не учитывало тестирование и возможных рисков, связанных с новым семейством процессоров. Написав драйвера для многих процессоров, разработчик был экспертом в этой области, и он согласился, что новый процессор лучше - по крайней мере, на бумаге. Тем не менее, он также знал, что модернизация существующего процессора до более новой модели в том же семействе даст почти те же преимущества, и при этом не потребуются никакие усилия для замены существующих драйверов. Он серьёзно сомневался, что архитекторы из башни из слоновой кости знали об усилиях и влиянии на разработку программного обеспечения - никто из них не говорил с ним; фактически они не общались с настоящими программистами.

Архитектурный фундамент? - “Важно иметь архитектурный фундамент, прежде чем реализовывать что-либо ещё, иначе у вас не будет архитектурного фундамента”. Эта ложная дихотомическая идея проистекает из метафоры здания, как будто программная система была сделана из бетона, а не из мягкого кода. Как будто основные элементы системы не могут быть улучшены с помощью циклов обучения и рефакторинга. По стечению обстоятельств, когда мы писали этот раздел, мы пили пиво в пабе Оксфорда, в Англии, с Алистером Кокберном (лидером мысли в гибкой разработке), который сказал нам, что он и его жена хотели добавить подвал в их существующий дом. Строители подняли весь дом, вырыли под ним подвал и поставили дом обратно. Удивительно, какие “архитектурные” фундаментальные изменения возможны, если мыслить нестандартно, а программное обеспечение всё же намного мягче, чем дома.

Конечно, важно иметь отличную архитектуру. Очень важно, чтобы каждый акт гибкого моделирования (Agile Modeling) и программирования для жизни системы рассматривался как архитектурный акт. Мы все согласны с тем, что хорошая архитектура важна; вопрос в том, каким способом достичь этого? Большинство советов в этом разделе содержат предложения о том, как создать и поддерживать отличный “фундамент”, который не основан на метафоре здания или последовательном жизненном цикле ПО.

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

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

Процессные рекомендации

Воркшопы по проектированию и моделированию

Воркшоп по сбору требования объединяет пользователей и разработчиков, чтобы они могли встретиться лицом к лицу. Они (воркшопы) чрезвычайно полезны не только для изучения потребностей пользователей, но и, что является ключевым моментом, для создания общего понимания среди всех участников.

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

Когда? - Подумайте о проведении воркшопов по проектированию на старте работ над каждым новым элементом Бэклога (например, три воркшопа по проектированию для каждого из трёх элементов в итерации) и “точно вовремя” тогда, когда команда решит, что необходимо перейти к моделированию на “стенах”.

design_ws_1.jpg
воркшоп по проектированию - фиче-команды моделируют на "белой доске" в общекомандном пространстве.

Что моделировать? - Во время воркшопа по проектированию фиче-команды фокусируются на моделировании, связанном с их предстоящими задачами, и/или общей архитектурой системы. Так происходят все виды проектирования и моделирования: проектирование пользовательского интерфейса с помощью набросков и заметок или инструментов для создания прототипов, моделирование алгоритмов с помощью UML-диаграмм, проектирование ООП-модели, обычно в нотации UML, и моделирование базы данных аналогичным образом.

gui_with_glue.jpg
моделирование применимо и к пользовательскому интерфейсу.

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

Громадные “доски” - Воркшопы по проектированию требует огромного пространства “белых досок”. Стандартные доски обычно не достаточны - и на самом деле часто являются препятствием, потому что моделирование лучше всего проводить на всей поверхности стен, без границ. Вам понадобится покрыть практически все пространство стен материалом “белых досок”, обычно высотой около двух метров.

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

В магазинах канцелярских товаров или на их сайтах вы можете купить “электростатические доски” или “липкие доски”, поверхность которых похожа на обычную “белую доску”, и которые удерживаются на обычной стене с помощью электростатики или клея5. Вы также можете купить “белые обои” - отличное решения для того, чтобы обклеить все пространство в комнате от пола до потолка. Одна компания, в которой мы работали, купила дешёвые стеновые ПВХ-панели для ванной комнаты, которые отлично работали в качестве досок; они покрыли ими всю комнату. Как только такие пространства “досок” сформированы, они остаются в таком состоянии навсегда.

cling_sheet_roll.jpg

Лучший инструмент для моделирования? – Я (Крэг Ларман) написал книгу Применение UML и шаблонов проектирования. Люди, которые знают об этом, иногда спрашивают меня, какой CASE (computer-aided software engineering, ПО для автоматизации разработки программ), MDD (model-driven development, разработка, управляемая моделями) или MDA (model-driven architecture, “архитектура, управляемая моделями”) инструмент я использую. Или, когда я организую воркшоп по проектированию, они могут спросить, как какой-либо из инструментов CASE/MDD/MDA настроить. Обычно они удивляются, когда я отвечаю: “Лучший инструмент для моделирования, который я знаю - это свежая чёрная маркерная ручка, группа людей и гигантское количество места на доске. Эскиз UML на стене - это здорово”.

Программы для построения UML иногда полезны, и в некоторых случаях мы рекомендуем их. Например, они могут пригодиться для автоматического и быстрого преобразования кодовой базы в набор диаграмм (реверсивного проектирования), помогающих увидеть общую картину. Но при использовании для прямого проектирования или генерации кода они, учитывая сегодняшние технические ограничения, могут препятствовать достижению некоторых важных целей, о которых мы ещё поговорим в статье.6.

uml_wall.jpg
полезные и простые UML-диаграммы в отличном UML-инструменте - на стене.

Совместное создание эскизов с помощью простого инструмента и испытанного временем многолетнего подхода являются одной из дисциплин гибкого моделирования.

Оставляя в стороне другие советы и практики гибкого моделирования, зачем мы совместно моделируем на воркшопах?

моделируйте чтобы общаться

Это повторение Первого Закона Диаграмм, описанного в Системном Мышлении:

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

Мы призываем команды не создавать модели ради создания спецификаций, а вести беседу - вместе исследовать и обсуждать, создавать общее понимание архитектуры и требований, помочь разработать общую ментальную модель и учиться вместе. Несомненно, некоторые объектно-ориентированные UML-модели или прототипы UI на стенах в конечном итоге будут успешно реализованы в коде, но это побочное преимущество, заключающееся в том, что вы найдёте время подумать, обсудить и набросать идеи вместе.

Модели - это не спецификации. Любая модель, созданная до того, как написан код - это всего лишь предположение (и повод для разговора), а не реальная архитектура, которая существует только в исходном коде. В гибком моделировании справедливо считается, что наброски и текст диаграммы являются источником вдохновения, а не спецификацией. Лучшая проектная документация (для целей сопровождения) создаётся после написания кода на SAD-воркшопах, описанных ниже.

Все модели “неверны”, и это нормально - люди обсуждают их, чтобы перенять новые идеи друг у друга и выровнять своё и общее понимание контекста. Естественно, что модели “неверны” и дизайн развивается, когда люди попадают в реальность программирования и обучения.

Фотографии, размещённые в вики. Команды часто фотографируют эскизы стен и размещают их на вики-пространстве своего продукта.

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

Снижение издержек,обучение. В бережливом мышлении основное внимание уделяется сокращению издержек, а бережливая разработка направлена на усиление конкурентного преимущества путём более быстрого обучения чем конкуренты. Воркшопы по проектированию поддерживают эти цели следующим образом:

  • Воркшопы уменьшают потери от передачи информации и задержек. Раньше, проектировщик или архитектор создавали проектную документацию и отправляли её разработчикам7 и получали отложенную обратную связь от них посредством непрямых способов коммуникации. Вместо этого, воркшопы собирают всех вместе и дают возможность дать быструю обратную связь напрямую. Это также поддерживает шестой принцип гибкой разработки - Непосредственное общение является наиболее практичным и эффективным способом обмена информацией как с самой командой, так и внутри команды.
  • Они сокращают потери информации, поскольку люди ведут живую беседу, обсуждая детали на доске.
  • Они сокращают потери недостаточной востребованности людей, поскольку люди учатся друг у друга и, таким образом, расширяют свои компетенции.
  • Они улучшают знания, как с точки зрения обучения других, так и с точки зрения генерирования новых идей посредством перекрёстного обмена мнениями группы из семи человек, творчески исследующей проблемы вместе.
  • В бережливой организации менеджеры и эксперты также являются учителями. Воркшопы по проектированию предоставляют для руководителей отличную возможность обучения других сотрудников навыкам проектирования и архитектуры.
  • Они помогают легче управлять процессом на основе визуализации.
  • Они способствуют бережливым принципам построения консенсуса и кросс-функциональной интеграции.
walls_in_halls.jpg
коридор - отличные место для размещения больших досок. Такие доски вовлекают других людей в практику гибкого моделирования, когда они проходят мимо команды, активно ведущей обсуждение "у стен".

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

Простой UML - поскольку люди хорошо воспринимают визуальную информацию (“пузыри и стрелки”, а не просто текст), мы призываем людей освоить азы нескольких UML-нотаций, включая диаграмму активностей, классов и взаимодействия. Но подробные обозначения совершенно не важны - модель нужна для иллюстрации дискуссии, а не для создания спецификаций.

Сколько времени может занять? – от двух часов до двух дней. Как и во всех Scrum-событиях, заранее запланируйте максимальную длительность воркшопа, чтобы люди могли правильно спланировать своё время.

Моделирование “Точно вовремя” (Just-in-Time, JIT); меняйте уровень абстракции

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

Обратите внимание, что это позволяет людям легко и просто менять уровень абстракции - от кода к моделям и обратно. Распространённая ложная дихотомия заключается в том, что единственное время для высокоуровневого проектирования системы - это этап предварительной разработки. Но это не так. С практикой гибкого моделирования в окружении, удобном для этого, люди могут постоянно переходить между уровнями абстракции.

Воркшопы по проектированию каждую итерацию

Запланируйте и проводите, по крайней мере, один воркшоп по проектированию в каждой итерации ближе к её началу. Если потребуется, то можно провести дополнительные воркшопы для каждого элемента Бэклога Спринта. Он должен быть ограничен по времени в диапазоне от двух часов до двух дней. На нём обычно рассматриваются задачи текущей итерации, хотя иногда проектирование на несколько спринтов вперёд тоже имеет смысл. Команда может провести небольшой воркшоп по проектированию до реализации первой задачи, затем ещё один через четыре дня до реализации второй и так далее.

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

Воркшопы по проектированию на рабочих местах команд

Это полезно, если стены каждой командной комнаты покрыты “белой доской”, чтобы можно было проводить воркшопы по проектированию. Когда разработчики сидят за рабочей станицей, они могут посмотреть на стены для понимания общей картины или встать около такой стены, чтобы быстро что-то обсудить. Это помогает с лёгкостью проводить проектирование “точно вовремя”.

design_ws-china.jpg
whiteboard_in_room.jpg
Команда окружена досками в её комнате; люди могут видеть модели на стенах при программировании и с лёгкостью проводить JIT-проектирование.

Многокомандные воркшопы для решения общих вопросов по проектированию

Как работать над проектированием и архитектурой на уровне системы? Как работать над вопросами проектирования кросс-системной “линейки продуктов”?

groups_in_ws.jpg

В более общем случае, предположим, что…

  • несколько фиче-команд работают над общим компонентом или фреймворком, поскольку фиче-команды работают над компонентами перекрёстно (кросс-компонентно) и синхронизируются на уровне кода
  • одна команда или вся продуктовая группа берет на себя разработку общей для всех задачи или инфраструктуры, которая в конечном итоге будет использоваться другими командами или продуктами
  • команды организованы как компонентные (т.е. субоптимально), а не как фиче-команды. Одна функция для конечного клиента (“фича”) проходит через несколько таких команд
  • представители нескольких команд собираются вместе, чтобы изучить и решить вопросы архитектуры и проектирования на уровне системы

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

Кто участвует в таких событиях? Члены фиче-команд, а также технические лидеры, пишущие код, а не PowerPoint-архитекторы или архитектурные астронавты.

Как часто? Проводите многокомандный воркшоп по проектированию по вопросам “архитектуры” продукта хотя бы один раз в несколько итераций.

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

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

Воркшоп по проектированию для нескольких команд - это активность сообщества практиков (Community Of Practice, CoP), в данном случае для проектного или архитектурного CoP. Итак, кто же организует регулярные многокомандные воркшопы по проектированию? Это может быть фасилитатор CoP воркшопов.

Есть ещё и другая причина проводить многокомандные воркшопы по проектированию, которая описана далее …

Технические лидеры ведут инженерные воркшопы

Проблема: отсутствие общих навыков проектирования и специальных знаний (об архитектуре, других компонентах,…). Образование - это лекарство. На бережливом производстве главные инженеры также являются учителями, тренируя людей в области инженерии. Во время воркшопов по проектированию технические лидеры, менеджеры и программисты-архитекторы помогают своей собственной “домашней” команде, или другим командам. Они могут провести много часов с одной командой у стен, помогая людям углубить их навыки, создавая и поддерживая таким образом архитектурную целостность.

wall_discussion.jpg

Архитекторы и системные инженеры являются постоянными членами фиче-команд

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

“Член команды” не означает человека, просто “приписанного” к команде. Т.е. это не тот человек, который получает задачи от одной или нескольких команд продукта, решает их сам и возвращает “свою” завершённую работу обратно в общий контекст.

Ставьте под сомнения все ранее принятые архитектурные решения

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

Не следуйте устаревшим архитектурным решениям

Наверняка, у всех разработчиков был такой опыт: “Ну, это довольно неудобно, но я впихиваю новое в уже существующий подход, потому что усилия на переделку не окупятся». Эти усилия делятся на 2 большие категории: технические и политические, чтобы убедить архитекторов, сидящих в башне из слоновой кости. В небольших системах культура “следования” по сравнению культурой “подвергай сомнению и улучшай” создаёт лишь небольшие проблемы, потому что технический долг не так велик… пока. В больших системах - или системах, которым суждено стать большими - этот технический долг становится чудовищным якорем, который сковывает всю продуктовую группу… навсегда. Особенно в первые годы, когда растущий продукт все ещё “мал”, вы хотите вдохновить людей чаще подвергать сомнению изначальные архитектурные решения и продвигать идеи глубоких изменений (достигнутые с помощью рефакторинга и непрерывной интеграции) до того, как “лодочный якорь” начнёт тащить ваш продукт под воду.

Избегайте архитектурных астронавтов (PowerPoint-архитекторов)

В небольших организациях мало денег и времени для “архитектурных астронавтов”, “PowerPoint-архитекторов” или архитекторов из башен из слоновой кости, которые описывают системы на абстрактных уровнях, но не могут их реализовать в коде и не имеют отношения к реальности это самого кода. В больших продуктовых группах такая роль часто появляется. В книге, которая получила премию Jolt Productivity Award 2005 (за вклад в разработку программного обеспечения), автор даёт комментарии:

Это люди, которых я называю Архитектурными Астронавтами. Их очень трудно заставить писать код или разрабатывать программы, потому что они не могут перестать думать об архитектуре… Они склонны работать на действительно большие компании, которые могут позволить себе иметь множество непродуктивных людей с учёными степенями, которые не добавляют ценности в конечный продукт.

В бережливом мышлении акцент делается на менеджерах-учителях, которые являются мастерами своего дела и наставниками для других, а также на работе в качестве “полевого” инженера в течение многих лет. Разработка больших продуктов в соответствии с практиками бережливого производства поощряет главного инженера обладать актуальной “высокой технической компетенцией”, а также видением бизнеса. Архитекторы, которые смотрят свысока на “только кодирование” как на нечто, что они уже переросли, не имеют места в бережливой или гибкой организации.

Как обсуждалось в разделе “Выращивание, а не строительство”, некоторые дисфункции возникают из-за убеждения, что код не является реальной архитектурой, и что технические лидеры не должны соприкасаться с его реальностью.

Кроме того, постоянно развивающиеся способы и инструменты проектирования ПО (разработка через тестирование (TDD), рефакторинг и т. д.) должны влиять на мышление технического руководства. Например, для реального понимания тонкостей и влияния TDD или рефакторинга требуется длительная практика “своими руками”. Без этого понимания “архитектор” не знает об определённых течениях, динамике или инструментах в разработке систем.

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

Этот совет не означает, что технические лидеры только сидят и программируют. Естественно, они принимают архитектурные решения и сообщают о важных из них (например, на воркшопах по проектированию с участием нескольких команд), а также остаются в курсе пересечений архитектурных решений с рыночными силами [Hohmann03].

Как вы видите на диаграмме причинно-следственных циклов выше (CLD, раздел “Размышления о проектировании”), много терминов, связанных с метафорой “архитектура”. “PowerPoint-архитектор” часто физически и социально не связан с реальной работой и реальными разработчиками, что несовместимо с принципом бережливого производства “иди и посмотри” (“Go See”)”.

Как можно раньше приступите к разработке “ходячего скелета” с кодом трассировки

Старый и мудрый совет состоит в том, чтобы разработать ходячий скелет системы, не важно большой или маленькой, как можно раньше. Это поможет получить знания о соответствующей архитектуре, запрограммировав и протестировав вертикальные и горизонтальные (и любые другие) срезы системы [Cockburn04], [Monson-Haefel09]. Это не разработка компонентов или слоёв отдельно, скорее это межкомпонентная, межуровневая “вертикальная” разработка, которая реализует ходячий скелет в коде. И при этом это не прототипирование; это качественная разработка кода, в котором реализуется архитектурный фундамент. Создание представляет собой учебный процесс, который может включать короткие циклы архитектурного анализа, воркшопы по проектированию и моделированию, программирование и рефакторинг архитекторами-программистами. Этот совет связан со многими последующими советами.

“Программная” часть этого совета, по сути то, что Хант и Томас назвали разработкой кода трассировки.

Инкрементально создавайте “вертикальные” архитектурные фрагменты в рамках клиентоориентированных элементов Бэклога

Я (Крэг Ларман) помню, как в 1995 году в ObjectSpace мы разрабатывали продукт для одной компании. Они хотели получать отчётность и управлять своими бизнес-консультантами и их навыками. По “византийским причинам”, выходящим за рамки этой истории, нам пришлось написать собственную подсистему объектно-реляционного отображения (ORM) на C++. Таким образом, в первых трёх итерациях (если я правильно помню, по три недели каждая) “талантливые” разработчики разработали компонент ORM, сосредоточив внимание на создании только этой части системы. Изящные прокси с отложенной инициализацией и умными шаблонными указателями, а также с другими чересчур гиковыми качествами. Затем представители клиента посетили демонстрацию прогресса. Команда была гордой.

Но клиенты были недовольны.

Они понятия не имели, в чем смысл нашего “изобретения”, и им казалось, что мы потратили девять недель их денег, не делая ничего, что им было нужно. Они просто хотели получать отчётность и управлять своими бизнес-консультантами. Они хотели отказаться от наших услуг.

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

В Scrum это означает создание элемента Бэклога Продукта в течение итерации полностью. В контексте XP это было названо разработкой пользовательской истории. В RUP это называется разработкой на основе сценариев использования.

Хотя в программном обеспечении нет как таковых “вертикалей”, учитывая то, как обычно изображаются структурные диаграммы программного обеспечения, но можно сказать, что “вертикально” - это когда реализовано сквозь все слои и компоненты (пользовательский интерфейс, база данных и т. д.). Для реализации истории или сценария пользователя, развивайте и внедряйте необходимую архитектуру для поддержки этого сценария, чтобы получить обратную связь. Вместо того, чтобы полностью разрабатывать “горизонтальные” подсистемы, отделённые от пользовательских функций, разрабатывайте вертикально по уровням и компонентам для выполнения этой функции, замедляя горизонтальное построение компонентов по мере того, как рассматриваются более ориентированные на клиента функции.

Эти “вертикальные” клиентские функции разрабатываются фиче-командами по Scrum.

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

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

Последнее утверждение - разработка, основанная на архитектурно значимых клиентоориентированных функциях - обсуждается в следующем совете…

В первую очередь берите в разработку ценные для пользователей задачи с наибольшем влиянием на архитектуру

Этот совет похож на некоторые из предыдущих, но с более сильным акцентом на приоритизации Бэклога, основанной на риске.

Несколько лет назад мы консультировали небольшую группу из 100 человек в Берлине. Одна из пользовательских историй от поддержки требовала масштабирования системы для обработки 80 одновременных сеансов с низким уровнем задержек. Делайте такие истории как можно раньше.

В модели “Инвариантной спиральной разработки” Барри Бёма, являющейся хорошей архитектурной практикой в масштабируемой разработке, пятый инвариант подразумевает, что ранние итерации фокусируются на архитектурном этапе в рамках жизненного цикла продукта. Результатом этого этапа являются основные элементы архитектуры (как аппаратные, так и программные) - они должны быть разработаны и проверены путём ранней интеграции и серьёзного тестирования производственного кода, а не путём предположений или простого прототипирования (хотя прототипирование может дополнять основное тестирование). Это очень разумный совет.

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

Этот совет является примером разработки через управление рисками (тема спиральных инвариантов). В данном случае рассматриваются два риска:

  • бизнес-риск - не соответствовать тому, что важно для клиента
  • технический риск - не построить целостную архитектуру

Оба должны быть рассмотрены на ранних итерациях. Ложной дихотомии тут нет.

Архитекторы проясняют дальнейший путь развития путём разработки “спайков”

В гигантском продукте, содержащем 20 миллионов строк кода, “архитекторам” соблазнительно и безопасно думать следующим образом: “Ну, это довольно большая и требующая рефакторинга на текущий момент система, и прошло уже 23 недели с тех пор, как я программировал последний раз. Мне намного проще написать документ, объясняющий, что я хочу изменить в архитектуре. Почему бы нет? Я знаю, что происходит”. Избегайте этого искушения; Покиньте свою зону комфорта. Поощряйте архитекторов, пишущих код, в первую очередь совершенствовать и находить идеи, разрабатывая “спайки” - один из вариантов исследовательского программирования, которое “пронзает” все компоненты приложения и позволяет понять жизнеспособность самой идеи [Beck99]. Используйте воркшопы по проектированию, гибкому моделированию или документированию системной архитектуры, чтобы передать знания другим разработчикам.

Не позволяйте архитекторам просто “передавать” требования конечным разработчикам

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

Команда “тигров” сначала работает вместе, и только потом разделяется

Для запуска нового или серьёзной переработки архитектуры существующего продукта попробуйте начать с команды “тигров”, состоящей из экспертных архитекторов-программистов, работающих вместе в одной комнате. Не начинайте с гигантской группы. Сохраняйте это команду “тигров” маленькой, пока это возможно; они сначала напишут тот код, что “победит” ключевые архитектурные препятствия.

Повторяя цитату (со страницы 1) о крупной разработке SAGE в 1950-х годах, старшего менеджера проекта спросили об извлечённых уроках:

Затем его спросили: “Если бы вы начали всё с начала, что бы вы сделали по-другому?” Он ответил: “Найдите десятерых лучших, и пусть они всё напишут сами”. [Horowitz74]

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

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

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

start_with_tiger_team.png
Начните *разработку* нового продукта с *одной* команды "тигров"start

Эльссамадиси и Эльшами назвали эту практику “Разделяй после того как уже властвуешь” (Divide After You Conquer).

Мы помним ужасную историю продуктовой группы, которая не последовала этому совету (мы начали их консультировать только во время 3-го релиза): их первый релиз был катастрофой. Что же произошло? Это был новый продукт, реализованный на C++. Они взяли Powerpoint-архитекторов из другого успешного продукта, основанного на устаревших технологиях. Эти “опытные эксперты”, которые никогда не использовали C++ или ООП (объектно-ориентированное программирование), приступили к написанию архитектурных документов. Затем 200 программистов, распределённых по двум разным офисам, одновременно начали разработку. Многие никогда не работали с ОО языком программирования, поэтому им дали возможность пройти трёхдневный курс по С++. Продукт опоздал на два года, и во время 3-го релиза они все ещё решали основные проблемы с качеством и переделывали “архитектуру”.

SAD-воркшопы в конце “тигровой” фазы

Воркшоп по документированию системной архитектуры (system architecture documentation, SAD) может быть полезен в конце “тигровой” фазы, чтобы обеспечить передачу знаний новым командам, которые вскоре будут созданы (см. То время, когда стоит провести SAD). Иногда может быть полезно запускать команды во время второго воркшопа по SAD. Обратите внимание, что все эти методы пытаются снизить потери при передаче информации. Прочтите последующие эксперименты, чтобы узнать больше о SAD-воркшопе и создании адаптивной документации по системной архитектуре.

tiger_team_SAD_workshop.png
То время, когда стоит провести SAD

Помогите “заразить людей” с помощью SAD-воркшопов

Потери, связанные с передачей знаний через документы, являются постоянным спутником в разработке программного обеспечения - такая передача просто не работает, как нужно. Действительно, архитектурные документы даже редко читаются конечными разработчиками. Таким образом, тема трёх советов заключалась в том, чтобы сосредоточиться на обучении разработчиков посредством их “заражения”, посредством тщательного и постоянного личного общения с экспертами-учителями, которые обладают современными инженерными технологиями, а также с другими техническими лидерами. Благодаря постоянному, в каждой итерации, участию в воркшопах по документированию системной архитектуры (SAD), парному программированию и ревью кода эти технические лидеры и эксперты-учителя “заражают” своих коллег всё более широкими и глубокими знаниями по архитектуре системы.

sad_workshop.jpg
воркшоп по SAD, зарисовка нескольких архитектурных схем. Обратите внимание на количество "белых досок"

Иногда, этот совет может быть интерпретирован, как ложная дихотомия: или воркшопы, или документы. Используйте оба подхода, особенно в крупных системах. Сделайте акцент на том, что эксперты - это учителя, и в то же время подкрепите это на SAD. Кроме того, разрабатывая документацию по системной архитектуре на SAD-воркшопах с участием группы среднего размера, часто с представителями многих команд, само мероприятие становится ещё одной возможностью для получения новых знаний.

Воркшопы по SAD отличается от воркшопов по проектированию. Чем?

  • Воркшопы по проектированию проводятся перед тем, как приступить к настоящему проектированию - написанию кода. Результатом воркшопа являются разговоры, обучение и размышления - зарисовки на стенах. Для крупных системных изменений применяются воркшопы по проектированию для нескольких групп. Не важно, для одного ли компонента или всей системы проводятся такие события, они всегда вдохновляют на творчество.
  • Воркшопы по SAD, наоборот, проводятся после реализации функционала (например, вскоре после выпуска каждые шесть месяцев). Воркшопы по SAD ретроспективно инспектирует законченную систему и описывает её. Такое событие в меньшей степени является творческим, но более информативным, так как участники узнают больше о существующей архитектуре и генерируют идеи для её улучшения, которые следует рассмотреть на будущих воркшопах по проектированию для нескольких команд.

В качестве материалов для SAD предложите модель представления и технические заметки версии N+1; см. главу Документирование архитектуры в [Larman04a].

Для фиксации информации после SAD сделайте фотографии рисунков N+1 версии на досках и сохраните их в вики. Кроме того, введите технические заметки на вики-страницах.

Эксперты обучают через ревью кода

Ревью кода обычно проводится для выявления дефектов и это редко делается старшими архитекторами продукта (так кажется). Но это событие можно использовать не только для обнаружения дефектов, но и для обучения, особенно для улучшения навыков проектирования и сохранения архитектурной целостности. Ключевым принципом бережливого производства является “Go See” или “Пойди и посмотри на реальное место возникновения проблемы и исправь его там”. Архитекторы или эксперты, которые пытаются установить и поддерживать архитектурную целостность только путём создания презентаций или документов, не добьются успеха. Но архитекторы, которые являются первоклассными программистами и которые регулярно проводят ревью кода (то самое “реальное место”) с разработчиками, имеют возможность обучать других этому мастерству самым действенным способом, а также придерживаться источника истинной архитектуры - кода. Этот совет фокусируется на экспертных сотрудниках, как на учителях.

Не ждите согласования ревью кода от экспертов

Что тут не так?

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

Наличие внешнего согласования также инициирует внешний процесс по отношению к команде; она больше не контролируют его и не может проводить эксперименты по улучшению.

В компании Nokia (где раньше работал Бас Водди) они применяли традиционный процесс согласования ревью кода: код был проверен и утверждён (или нет) после того, как он был полностью написан. Как и в случае с потерями при передаче, были задержки при рассмотрении, и обратная связь была неявной. Плюс, если были необходимы правки, цикл повторялся вновь и вновь.

Чтобы это улучшить, они представили технику под названием RaPiD7 [Kylmäkoski03]. Документ писался и утверждался в ходе одного воркшопа с участием всех необходимых заинтересованных сторон, уровень знаний повышался, и поэтому не было необходимости в отдельном цикле проверки / согласования.

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

Сообщество практиков по проектированию и архитектуре

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

Практика “покажи и расскажи” в время воркшопов

Если команды продукта участвуют в общем воркшопе по проектированию, то будет полезным для взаимного обучения командам посещать “стены” других команд по несколько раз, проводя сеансы “покажи и расскажи”. Это также полезно, если одна команда (например, из семи человек) решает разделиться на две подгруппы во время воркшопа и параллельно моделировать различные функции. Группа-1 подходит к стене Группы-2, чтобы увидеть и изучить идеи проектирования и помочь их развить. И наоборот.

Менторы компонентов для поддержания архитектурной целостности при коллективном владении кодом

Успешный переход от единоличного к коллективному владению кодом, поддерживаемый гибкими практиками, не происходит в одночасье. Практика компонентных менторов может помочь. У “хрупких” компонентов (для которых актуальна проблема8) есть наставник, чья роль состоит в том, чтобы обучать других людей, и который следит за тем, чтобы изменения, производимые в нём, были грамотными, и помогает уменьшать хрупкость этого компонента. Он не является владельцем компонента, изменения вносятся всеми членами всех фиче-команд. Новичок (или новая команда) в компоненте просит наставника компонента научить его и помочь внести изменения, например, на воркшопах по проектированию и/или посредством парного программирования. Наставник также может проверять все изменения с помощью инструмента “diff”, который автоматически отправляет ему электронные письма с изменениями. Эта роль отчасти похожа на роль коммиттера в разработке с открытым исходным кодом, но с ключевым отличием - без запрета коммитов других участников; запрет может создать узкие места и задержки9. Они являются учителями и разработчиками компонентов, а не их “привратниками”. Компонентный наставник - ещё один пример бережливой практики регулярного наставничества со стороны экспертов и повышения общего уровня знаний.

Списки рассылок компонентов

Другой способ поддержки практики коллективного владения кодом - это список рассылок (или другой канал коммуникации) для каждого “деликатного” компонента. Люди, часто работающие над компонентом, могут обсудить рефакторинг, структуру, ошибки, произвести ревью кода, объявить об обучении и так далее. Конечно, любой может присоединиться или покинуть список в соответствии с потребностями, но наставники компонентов являются долгосрочными членами данных списков рассылок.

Практики менторинга и открытый внутренний исходный код (internal open source)

Гибкая разработка приветствует коллективное владение кодом. Фиче-команда подразумевает работу над всем необходимым кодом в рамках задачи. В этом смысле гибкая разработка похожа на модель internal open source, но с разницей в ещё большем коллективном владении кодом и отсутствием “привратников”, которые создают задержку. Если необходимо, наставники компонентов помогают с решением сложных задач, не блокируя их. Для тренеров по гибкой разработке “internal open source с несколькими наставниками” могут быть более лёгким способом объяснить идею коллективного владения кодом, потому что большинство людей знают, что различные модели работы с открытым исходным кодом могут быть полезными.

Распространите эту практику и на внутренние инструменты, а не только на общие компоненты. Вместо того, чтобы “команда в Польше поддерживает наш инструмент тестирования”, поэкспериментируйте с внутренним (или даже общедоступным) общим кодом или моделью с открытым исходным кодом. Хорошие разработчики осваивают и развивают свои инструменты; эта модель способствует этому.

Во время проектирования закладывайте возможность конфигурации архитектуры для кастомизации

Некоторые из наших клиентов копают себе довольно глубокую яму, создав отдельные ветки для кастомизации своего продукта для разных клиентов. Те, кто испытал это - особенно в очень больших системах - слишком хорошо знают, что это всё становится “болью” в конфигурации, обслуживании и тестировании по мере того, как развивается продукт и количество требуемых сопровождения веток только увеличивается.

Вместо веток закладывайте возможность конфигурации (например, с использованием метаданных или плагинов), которая позволит активировать/включать (или не включать) определённые компоненты или функции.

Используйте архитектурные шаблоны и шаблоны проектирования

Детальный архитектурный дизайн для больших систем выходит за рамки текущей темы, которая выделяет советы по проектированию, ориентированные на процесс. Но существует множество надёжных решений в рамках сообщества развития шаблонов проектирования, помогающих создать гибкую архитектуру. Читайте книги из нашего списка и пробуйте подходы, описанные в них (см. “Рекомендуем к прочтению”).

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

Девятый принцип Agile-манифеста уделяет внимание хорошему проектированию: Постоянное внимание к техническому совершенству и качеству проектирования повышает гибкость проекта.

Развивайте общий словарь терминов

Если технические лидеры постоянно развивают и используют в разговоре известные термины и шаблоны, то это помогает улучшить общее понимание проекта и, возможно, повысить архитектурную целостность. Частично это происходит благодаря созданию общего словаря среди разработчиков. Шаблоны имеют официальные опубликованные имена, такие как Layers, MVC, MVP, Strategy, Broker, Service Locator и т. д. Таким наименования могут использоваться в документации, речи и коде, например, в имени интерфейса RoutingStrategy. Хотя основная ценность шаблонов заключается в переиспользовании устоявшихся решений, они также могут создать общий словарь в вашей команде. Это может помочь при масштабировании разработки на 300 человек, распределённых в разных офисах компании.

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

Инженерные рекомендации

За то время, что мы работали с крупными продуктами, обычно это были встраиваемые системы (embedded systems), мы составили список общих рекомендаций, которые могли бы уменьшить часть боли и страданий, которые на наших глазах испытывают наши клиенты. В этом разделе перечислены некоторые из этих советов. Но на самом деле эта тема заслуживает отдельной книги…

Представьте ваш исходный код в виде HTML-страниц и гиперссылок между ними

В небольшом проекте можно быстро перемещаться по всему исходному коду, просто открытому в вашей среде разработки. Когда, к примеру, имеется 36 839 файлов и 15 миллионов строк, навигация затрудняется. Используйте бесплатные инструменты, такие как Doxygen (www.doxygen.org), чтобы преобразовать ваш исходный код в набор HTML-страниц, в которых все структурные элементы (классы, методы, …) являются гиперссылками. Doxygen (и аналогичные инструменты) также будут генерировать диаграммы, отражающие более крупные компоненты и группы в вашей кодовой базе. Регенерируйте страницы ежедневно. Это очень полезно для понимания и развития огромной кодовой базы.

Используйте заглушки и внедрение зависимостей (dependency injections)

Создавайте заглушки10 - или “подменные” альтернативы кода для многих вещей: классов, интерфейсов с другими компонентами, аппаратного обеспечения и так далее. Заглушки обычно создаются с помощью альтернативной реализации интерфейса, путём наследования от “реального” класса в объектно-ориентированных проектах, с помощью указателей на функции или альтернативных файлов реализации при изменении пути ссылок в проектах на основе C [Feathers04], например:

{% highlight java %}
interface PrinterMotor {
void start();

}

class CanonPrinterMotor implements PrinterMotor {

}

class PrinterMotorStub implements PrinterMotor {

}
{% endhighlight %}

Если нет интерфейса (и даже если он есть), заглушки могут быть созданы с помощью наследования и переопределения соответствующих методов:

{% highlight java %}
class CanonPrinterMotor {

}

class PrinterMotorStub extends CanonPrinterMotor {

}
{% endhighlight %}

Кроме того, обеспечьте “чёрный ход” во многих классах, который позволяет легко внедрить не реальный объект, а альтернативную заглушку как зависимость; например, с помощью внедрения зависимостей через конструктор [Fowler04].

{% highlight java %}
class LaserPrinter {

private PrinterMotor motor = new CanonPrinterMotor(); // default …
public Printer( PrinterMotor alternativeMotor ) {
motor = alternativeMotor;
}
}
{% endhighlight %}

Сочетание множества заглушек с множеством “чёрных ходов” для внедрения зависимостей открывает огромные преимущества: усиление параллельной разработки, ранняя интеграция с заглушками, когда реальные компоненты недоступны, тестирование с заглушками, заглушки, которые предоставляют быстрые и хорошо известные демонстрационные данные. В контексте разработки крупных продуктов массовое использование заглушек - это ключевой метод для параллельной работы и ускорения работы, что сокращает затраты на ожидание.

Не используйте заглушки, чтобы отложить этап настоящей интеграции

Чудесно! Теперь у каждого есть заглушки и у вас есть возможность отложить этап настоящей интеграции всего кода на месяц или год. Даже не думайте.

Практикуйте разработку через тестирование для создания лучшей архитектуры

TDD может улучшить архитектуру системы. Как?

Когда мы занимаетесь обучением, частым запросом наших клиентов являются просьбы помочь с “негибкой архитектурой”. Чаще всего это в итоге оказывается следствием проблем сильной связанности компонентов - распространённая проблема в унаследованном (legacy) коде, написанном без использования TDD, потому что первоначальный автор не пытался тестировать компоненты изолированно.

С другой стороны, когда разработчик создаёт новый компонент (например, класс) с TDD или проводит рефакторинг устаревшего, то нужно избавиться от зависимостей компонента, чтобы он мог быть протестирован изолированно. Это требует проектирования (или рефакторинга) для внедрения зависимостей и более широкого использования механизмов для обеспечения гибкости: интерфейсов, полиморфизма, шаблонов проектирования, структур внедрения зависимостей, указателей на функции и многого другого.

В таком случае TDD подталкивает к слабому связыванию, простоте, гибкости конфигурации - качествам хорошей архитектуры.

Используйте операционную систему как уровень абстракции

Мы работаем с двумя клиентами над похожими продуктами - крупными встраиваемыми системами. Клиент А создал собственную операционную систему (ОС) и сделал последующие слои напрямую связанными с ней. Клиент B создал уровень абстракции ОС поверх своей первоначально используемой ОС (VxWorks) - ещё один слой абстракции для снижения связанности в этой точке вариативности. В какой-то момент оба клиента решили перейти на операционную систему реального времени на основе Linux. Клиент B закончил порт через пару месяцев. Прошло уже несколько лет, а Клиент А все ещё проводит исследования на предмет возможности перехода. Гибкость достигается благодаря низкой связанности слоёв программного обеспечения.

Этот совет автоматически выполняется, если вы используете Java или аналогичную платформу (которая использует виртуальную машину в качестве runtime). Однако большинство наших клиентов при разработке встраиваемых продуктов используют C/C++ стек. В этом случае попробуйте один из существующих уровней абстракции ОС с открытым исходным кодом, например Boost или Apache Runtime Library.

Введение в Интерфейсы и советы по Взаимодействию

Определение и развитие интерфейсов между компонентами и межкомпонентное взаимодействие являются основными вопросами при разработке больших систем. Фактически, это то, что Грэди Буч11 назвал “проектированием на стыках” [Booch96], что часто является доминирующей архитектурной проблемой в крупных приложениях. Также обратите внимание, что “боли интеграции” в географически распределённых или сверхбольших продуктах является отражением взаимодействия команд, их разрабатывающих. Когда вы работаете с монстром из 15 миллионов строк, состоящим из 234 основных компонентов, каждый из которых содержит в среднем по 64 тысячи строк, то, как правило, в повседневных архитектурных задачах преобладают именно вопросы взаимодействия и интерфейсов, а не дизайна какого-либо одного модуля или даже его наличия или отсутствия.

Интерфейсы / Interfaces – в этом разделе под термином “интерфейсы” мы понимаем следующее:

  • Интерфейсы в языках программирования, например в Java или C# (локальные или внешние)
  • Сигнатуры операций (имя функции и её параметры)
  • Интерфейсы Web-сервисов (например, WSDL)
  • и тому подобное

Большие системы обычно имеют солидный возраст; много кода на C для таких систем нормально, и “интерфейс” для другого компонента может быть просто сигнатурой функции, такой как debit( int, float ) . Другой контекст этих советов состоит в том, что в группе из 250 человек программист, использующий опубликованный API, может отличаться от программиста, который создавал его реализацию много лет назад.

Избегайте подробного проектирования интерфейсов на старте

Старая и бесполезная стратегия для решения проблемы интерфейсов звучала, как “Перед программированием определите и зафиксируйте интерфейсы между основными компонентами. Затем используйте процесс управления изменениями, когда интерфейсы будут меняться”. Эта модель разработки, ориентированная на раннее проектирование, вызывает следующие проблемы:

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

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

Упрощайте координацию процессом изменения интерфейсов путём создания фиче-команд

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

Избегайте “замороженных” интерфейсов

Есть моменты, когда публичный API действительно необходимо “заморозить”. Но оспаривайте эти решения, держите как можно больше артефактов доступными для изменения и экспериментируйте с методами поддержки эволюции интерфейсов. Некоторые методы будут предложены здесь, а другие - в разделе Рекомендуем к прочтению.

Оборачивайте вызовы внешних компонентов с помощью Proxy или Adapter

Внешние компоненты, вызов которых происходит через JMI, RPC, SOAP, промежуточное ПО на основе обмена на сообщениями (message-oriented middleware, MOM) или сокеты, являются гарантированными точками, в которых могут быть внедрены заглушки для возможности изолированного тестирования без обращения к реальным внешним компонентам. Кроме того, часто меняется сам протокол удалённого взаимодействия (например, переход с RPC на MOM).

Следовательно, вы должны защититься в этих точках вариативности, всегда оборачивая вызовы во внешние компоненты посредством объектов и полиморфизма, используя шаблоны проектирования Proxy или Adapter [GHJV94].

Начинайте с использования интерфейсов во взаимодействии основных компонентов, потом замените их, если потребуется

Большие системы обычно состоят из сотен основных компонентов, и они могут быть как “соседними”, так удалёнными друг от друга. Мы видим общие проблемы, связанные с взаимодействием между основными компонентами (такими как подсистемы) в больших системах:

  • зависимость от знаний того, какой основной компонент является получателем сообщения или вызова операции
  • зависимость от знаний протоколов взаимодействия, таких, как прямой вызов функции, RPC, SOAP через HTTP и т. д.
  • обработка сложных и повторяющихся ошибок сети
  • невозможность использования подключаемых модулей / компонентов из-за проблем, связанных с их сильной связанностью

Следующий совет может помочь …

Профессор информатики Дэвид Уилер (David Wheeler), как известно, говорил: “Любая проблема в информатике может быть решена введением дополнительного уровня абстракции”.

Решение вышеуказанных проблем заключается в использовании косвенного механизма связи между основными крупными компонентами (такими как подсистемы), в отличие от чего-то прямого, такого как вызов Java RMI или SOAP. Это “косвенное взаимодействие” глубже, чем просто добавление адаптера или прокси между компонентами; это означает использование какой-либо формы абстрактной системы обмена сообщениями.

Существует несколько вариантов непрямого обмена сообщениями между основными крупными компонентами. Одним из надёжных вариантов является промежуточное программное обеспечение, ориентированное на сообщения (MOM), такое как JMS и MSMQ. MOM, богатый опциями, поддерживающий плагины, заслуживает внимательного изучения. Подходят как шины MOM созданные самостоятельно, так и готовые решения с открытым исходным кодом. Выполнение межкомпонентной связи с помощью MOM предоставляет степень свободы, которая обеспечивает более низкую связанность и архитектуру, позволяющую использовать плагины. Решения MOM также предлагают встроенные функции сетевой отказоустойчивости и восстановления.

Также существует вторая часть цитаты Уилера, которая наименее известна. Приводим цитату полностью:

Любая проблема в информатике может быть решена введением дополнительного уровня абстракции. Но обычно это создаёт другую проблему.

Иногда, “другая проблема” - это влияние на производительность.

Потенциальным недостатком MOM является снижение производительности. В этом случае, как и в случае со слабо типизированным интерфейсом, вы можете начать с решения MOM, чтобы обнаружить “протоптанные тропинки” в коммуникации модулей, игнорируя при этом снижение производительности. Затем, по мере стабилизации каналов взаимодействия и обнаружения узких мест с точки зрения производительности, вы замените медленные взаимодействия MOM более быстрыми механизмами, такими как Java RMI. Это ещё один пример “вытягивающего” проектирования. MOM остаётся механизмом по умолчанию, если он не является критичным по производительности в конкретной ситуации.

Если этот совет сочетать с рекомендацией всегда использовать Proxy или Adapter для связи с внешними компонентами, то изменение протокола с MOM на RMI на внутренний код никак не влияет - нужно просто добавить альтернативный адаптер.

Заключение

Здания жёсткие и статичные. Программное обеспечение гибкое и динамичное.* Таким образом, “архитектура” далека от идеальной метафоры для создания программного обеспечения; это может даже способствовать неправильному пониманию того, что существует какая-то архитектура, оторванная от исходного кода, и что она по существу не меняется.

Но программное обеспечение постоянно развивается и обновляется с каждой модификацией исходного кода каждым программистом. Ключевой вопрос: станет ли оно красивым и ухоженным садом или джунглями сорняков?

Советы, приведённые здесь, вдохновляют на высококачественное эмергентное проектирование, благодаря культуре выращивания и более коротких и ценных циклов обратной связи, а не “архитектуре”. А для этого нужны великие садоводы: архитекторы-программисты, которые активно реализуют архитектуру в коде и постоянно обучают других программистов во время парного программирования и воркшопов по моделированию.

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

Мы не предлагаем никакой ложной дихотомии между разработкой и проектированием; последнее ценно, особенно в крупных системах. Помимо фокуса внимания на коде, гибкие воркшопы по моделированию - это отличная и легковесная техника, позволяющая быстро исследовать сложные конструкции и учиться вместе. Возможно, ключевым ингредиентом являются массивные пространства “белых досок”, поэтому захватывайте все стены!

Рекомендуем к прочтению

  • Сайт www.codingthearchitecture.com подчёркивает необходимость того, чтобы архитекторы были опытными действующими разработчиками.
  • Многие из наших клиентов имеют огромное количество “грязного” унаследованного кода, который сложно протестировать изолированно и трудно поддерживать. Книга Майкла Физерса Working Effectively with Legacy Code является важным противоядием, описывающим методы, позволяющие разработчикам начать разработку более гибкой архитектуры в рамках существующей кодовой базы.
  • Ключевым элементом технической гибкости является шаблон проектирования. Рассмотрим следующие статьи на эту тему: Design Patterns, Pattern-Oriented Software Architecture (в 5 томах), Applying UML and Patterns, and Pattern Languages of Program Design (в 5 томах).
  • Две книги Боба Мартина вдохновляют на адаптивную архитектуру: Agile Development, Principles, Patterns and Practices и Clean Code: A Handbook of Agile Craftsmanship. - ещё две полезные книги, ориентированные на качественный код, включают: Code Complete Стива Макконнелла и Implementation Patterns Кента Бэка.
  • Growing Object-Oriented Software, Guided by Tests Стив Фриман и Нат Прайс укрепляют культуру “выращивания”, а не определяют “архитектуру”.
  • Domain-Driven Design Эрика Эванса поощряет вдумчивый итеративный дизайн, общее понимание и модель предметной области, которая должна быть хорошо выражена в коде.
  • Статья Agile Product Development исследует бизнес-ценность разработки продукта и гибкости дизайна, а также то, как можно измерить гибкость разработки.

Сноски

  1. Нет никакой ложной дихотомии. Этот пример не означает, что нужно избегать технического совершенства или тщательного проектирования. Он лишь предлагает проектирование и архитектуру, которые прекрасно адаптированы быть более отзывчивыми к новым знаниями.
  2. Это разные вещи. Когда вы создаёте материальный объект, такой как аппаратное устройство; мы имеем в виду архитектуру программного обеспечения.
  3. Термин “архитектура программного обеспечения” не является “истиной”; название случайно возникло у некоторых молодых людей, которые искали аналогии. Как и все аналогии (включая “садоводство”), он имеет свои сильные и слабые стороны.
  4. Трёхмерная (3D) печать, в которой сложные объекты создаются на 3D-принтере, аналогична в этом отношении.
  5. Например, Write-On Cling Sheets или Magic Chart.
  6. Примечательно, но мы знаем нескольких людей, которые работали на поставщиков инструментов CASE/MDD/MDA, но сами эти инструменты при разработке они не использовали. Также следует отметить, что программисты в компаниях-производителях инструментов CASE/MDD/MDA часто не используют свой собственный инструмент для разработки своего же собственного инструмента!
  7. Это может быть полезно для создания проектной документации, но для уменьшения потерь при передаче подходящее средство для обсуждения и понимания идей, также и во время воркшопа по проектированию - только у “стен”.
  8. Типичная причина для беспокойства по поводу “особых” компонентов заключается в том, что код не “чистый”, хорошо переработанный и окружён множеством модульных тестов. Решение состоит в том, чтобы его очистить (“остановить и исправить”), после чего наставник компонента может и не понадобиться.
  9. Но роли не идентичны. Опекуны (или “стюарды”) проводят больше времени в обучении и программировании в паре, позволяют коммиты в любое время. Коммиттеры также обучают, но немного меньше, и контролируют коммиты кода.
  10. Некоторые неправильно используют термин mock, когда подразумевается заглушка или, в более широком смысле, тестовый дублёр. Мартин Фаулер говорил об этом в своей статье “Mocks Aren’t Stubs”. На практике заглушки встречаются гораздо чаще, чем mocks Meszaros07.
  11. Программное обеспечение является быстро меняющейся областью; лидеры мысли быстро исчезают за одно поколение. Не пропустите изучение работ Грэди Буча, пионера OO разработки.

Перевод статьи осуществлён Кротовым Артёмом и Титовым Игорем.