Одно из самых простых и конструктивных определений архитектуры дал Гради Буч (Grady Booch): «Любая архитектура является результатом проектирования, но не любое проектирование направлено на создание архитектуры. Архитектура служит представлением важных проектировочных решений, формирующих систему, причем важность здесь определяется стоимостью изменений». Отсюда следует, что эффективной является та архитектура, которая в общем случае снижает важность решений, принятых в ходе проектирования. Неэффективная архитектура эту важность увеличивает.
Если проектировочное решение может повести по одному из двух путей, архитектор должен отступить на шаг. Вместо того чтобы выбирать между вариантами А и Б, он должен подумать над другим вопросом: «Как спроектировать решение, чтобы снизить важность выбора между А и Б?». В этой ситуации интересен не выбор между А и Б, а сам факт существования этого выбора (а также то, что правильный выбор необязательно очевиден или неизменен).
Иногда архитектору приходится ходить кругами, прежде чем его озарит и он распознает возникшую дихотомию. Вы стоите у доски, обсуждая (весьма энергично) разные варианты с коллегой? Вы задумчиво бормочете «М-м-м» и «Э-э-э» над кодом, бесконечно перебирая возможные реализации? Когда новое требование или уточнение существующего требования ставит под сомнение разумность текущей реализации, перед вами неопределенность. Как реагировать на нее? Подумайте, как с помощью разделения или инкапсуляции изолировать принимаемое решение от кода, который в конечном итоге зависит от этого решения. Альтернативой этому часто становится невнятный код, который, словно нервничающий человек на собеседовании, бормочет что-то невразумительное и пытается компенсировать неуверенность множеством догадок и общих фраз. А если выбор делается с твердой, но необоснованной уверенностью, то проект на полной скорости и без оглядки сворачивает на неверный путь.
Часто возникает искушение принять «решение ради решения». В таких ситуациях вам поможет опционное мышление.[11] Если существует неопределенность относительно различных путей, по которым может пойти разработка системы, примите решение не принимать решение. Отложите конкретное решение до того момента, когда его можно будет принять более ответственно на основании реальных знаний, но не слишком надолго, чтобы не попасть в ситуацию, когда эти знания уже бесполезны.
Архитектура и процесс разработки тесно переплетены; это главная причина, по которой архитектор должен отдавать предпочтение таким циклам разработки и архитектурным подходам, которые имеют эмпирическую природу и обеспечивают обратную связь, чтобы конструктивно использовать неопределенность для деления на части самой системы и графика ее разработки.
Проблемы могут быть больше, чем их отражение в зеркале[12]
Я работал над сотнями программных проектов. В каждом из них встречались проблемы, которые создавали больше неприятностей, чем ожидала команда разработчиков. При этом часто происходило следующее: некоторые члены команды замечали такие проблемы рано, однако большинство сотрудников отвергало или игнорировало все симптомы, поскольку не понимало их важности, пока не становилось слишком поздно.
Это случается по разным причинам:
• Проблемы, которые кажутся тривиальными на ранней стадии проекта, становятся критическими тогда, когда их уже поздно исправлять. История про сварившуюся лягушку, вероятно, является преувеличением, однако она прекрасно иллюстрирует то, что творится во многих проектах.
• Некоторые сотрудники часто сталкиваются с сопротивлением в тех случаях, когда другие члены команды не обладают сходным опытом или знаниями. Для преодоления этого сопротивления необходимы исключительная смелость, уверенность и настойчивость, а подобными качествами редко обладают даже высокооплачиваемые опытные консультанты, нанятые специально для предотвращения таких проблем.
• Большинство разработчиков — оптимисты. Горький жизненный опыт учит нас умерять свой оптимизм, но неофиты склонны смотреть на мир оптимистично. Люди, от природы пессимистичные, в командах обычно непопулярны, даже если раз за разом оказываются правы. Мало кто захочет рисковать своей репутацией и пойдет против большинства без очень серьезных оснований. Многим из нас знакомо ощущение «не нравится мне все это, но не могу объяснить почему», однако оно редко становится действенным доводом в споре.
• У всех членов команды есть собственное мнение о том, что важно, а что нет. При этом их внимание сфокусировано на том, за что они отвечают лично, а не на целях проекта.
• У каждого из нас есть свои «слепые пятна» — слабости и недостатки, которые нам трудно осознать или принять.
Вот возможные стратегии противодействия этим факторам: