понедельник, 11 ноября 2013 г.

Кому нужен архитектор?

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

Недавно я наткнулся на статью Мартина Фаулера “Who Needs an Architect?” и просто не смог пройти мимо, поскольку в ней даются очень интересные определения архитектора и архитектуры. Ниже представлен перевод этой статьи с моими аннотациями по ходу дела.

---------------------------

Как-то совсем недавно, я встретил в коридоре своего коллегу Дейва Райса (Dave Rice) в особенно скверном настроении. Мой короткий вопрос привел к суровому ответу: "Мы не должны интервьюировать кандидатов, в резюме которых упоминается должность "архитектор". На первый взгляд мне это высказывание показалось странным, поскольку обычно мы представляем всем Дейва, как одного из наших ведущих архитекторов.

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

Что такое архитектура?

Когда я думал о названии своей книги "Архитектура корпоративных приложений" (Patterns of Enterprise Application Architecture, Addison-Wesley, 2002), все ее редакторы сходились во мнении, что слово "архитектура" в ее названии является подходящим, хотя никто из нас не смог точно определить его значение. Поскольку это была моя книга, я чувствовал необходимость сделать сноску, в которой дать определение этого понятия.

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

В одном из сообщений в группе рассылки говорилось следующее:

RUP (Rational Unifying Process), взяв определение IEEE, определяет архитектуру как "наиболее высокоуровневую концепцию системы в определенном окружении. Архитектура программной системы (в конкретный момент времени) представляет собой организацию или структуру важных компонентов, взаимодействующих посредством интерфейсов; компоненты, в свою очередь, состоят из меньших компонентов и интерфейсов."

На что Джонсон ответил:

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

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

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

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

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

Является ли некоторое решение архитектурным полностью зависит от того, считают ли разработчики его важным или нет. Разработчики "корпоративных приложений" (enterprise applications) обычно считают слой сохранения данных важным. Когда они начинают рисовать архитектуру своих проектов, то начинают с трех уровней приложения. Они скажут, что "мы используем Oracle в качестве базы данных и свой собственный слой доступа к данным для соответствия объектной модели данным в базе данных". Но медицинское приложение для работы с изображениями может использовать Oracle, не считая это решение архитектурным, потому что основная сложность такого приложения заключается в анализе изображений, а не в их хранении. Чтение и сохранение изображений реализовано в одной небольшой части приложения и большинство разработчиков могут это игнорировать.

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

Роль архитектора

Итак, если архитектура – это нечто важное, тогда архитектор – это человек (или люди), которые беспокоятся о важных вещах. И вот тут мы сталкиваемся с принципиальным отличием между видом архитектора, представленном в Матрице Перезагрузке и архитектором, примером которого является Дейв Райс.

Архитектус Релоадус (Architectus Reloadus) – это человек, принимающий все важные решения. Он делает это, поскольку должен быть единственный разум, обеспечивающий концептуальную целостность системы, а может потому, что он не думает, что в команде есть еще кто-то с достаточным опытом для принятия этих решений. К тому же, обычно эти решения должны приниматься рано, чтобы у всех был план, которому нужно следовать.

Архитектус Оризус (Architectus Oryzus) относится к другому виду животных (если не можете догадаться, почему он так называется, то посмотрите здесь - www.nd.edu/~archives/latgramm.htm). Этот вид архитектора должен быть максимально внимательным к тому, что происходит на проекте, выискивая важные проблемы и решая их до того, как они приведут к серьезным неприятностям. Когда я вижу архитектора такого рода, то легко заметить, что наиболее существенная часть его работы заключается в тесном общении с другими людьми. Утром архитектор программирует с одним из разработчиков, пытаясь разобраться с назойливой проблемой блокировок. После обеда он участвует в митинге по сбору требований, объясняя бизнес-пользователям технические последствия их идей в нетехнической форме, как, например, с помощью понятия стоимости разработки.

Что делает компонент важным? Он важен, поскольку разработчики-эксперты считают его таким.

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

На недавней поседелке в ThoughtWorks мы с некоторыми моими коллегами говорили о проблеме архитекторов. Интересно, что мы быстро сошлись на том, что должен делать архитектор, которого мы сейчас называем Архитектус Оризус, но мы долго не могли дать этому определению подходящее имя. Архитектус Релоадус является слишком распространенным понятием, чтобы мы могли спокойно его использовать в качестве определения "архитектора", к тому же оно построено на неудачной аналогии (см. http://martinfowler.com/bliki/BuildingArchitect.html). Майк Ту (Mike Two) предложил лучшее определение, которое я когда-либо слышал: проводник, как в альпинизме (guide, as in mountaineering). Проводник – это более опытный и умелый член команды, который учит других членов команды лучше справляться со сложностями, являющиеся неотъемлемой частью нашей работы.

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

Я люблю использовать поразительные заголовки, лучшие из которых (как вот этот) несут важную информацию, неочевидную с первого взгляда. Помните второе определение Джонсона: "Архитектура – это набор решений, которые вы бы хотели принять верно на ранних этапах работы над проектом". Почему кто-то хочет, чтобы некоторые решения были правильными с самого начала? Конечно же потому, что они думают, что их будет сложно изменить позднее. Так, мы можем прийти к определению, что архитектура – это “решения, изменить которые считается сложным”.

Существует распространенное мнение, что при разработке корпоративного приложения, вы должны сразу же разработать правильную схему базы данных, поскольку ее будет сложно изменить позднее, особенно после выпуска приложения в мир. На одном из наших проектов администратор баз данных Прамод Садаладж (Pramod Sadalage) придумал систему, которая позволяла легко изменять схему базу данных (и мигрировать данные) (см. http://martinfowler.com/articles/evodb.html).

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

В потрясающем выступлении на конференции XP 2002 (http://martinfowler.com/articles/xp2002.html) экономист Enrico Zaninotto проанализировал идеи, которые лежат в основе гибких методологий на примере производства (manufacturing) и разработки ПО. Мне очень понравился его комментарий, в котором он сказал, что необратимость (irreversibility) является главной причиной сложности. Он видел в гибких методологиях, применяемых в производстве и разработке ПО, сдвиг в борьбе со сложностью путем уменьшения необратимости, в противоположность общепринятым принципам борьбы со сложностью. Мне кажется, что одной из главных задач архитектора является удаление архитектуры путем устранения необратимости в дизайне ПО.

ПРИМЕЧАНИЕ
Является ли модель распределенного взаимодействия архитектурным решением? Многие считают, что да, является, и строят все приложение исходя из того, что компоненты приложения будут взаимодействовать посредством обмена сообщений. Я же стараюсь подходить к дизайну приложений таким образом, чтобы решение о конкретной модели распределенного взаимодействия была, по возможности, деталью реализации лишь нескольких компонент. Тогда, когда мы поймем, что текущая модель нам не подходит, мы не бросимся переписывать все приложение заново, а сможем относительно спокойно заменить ее на другую.

И вот еще мысли Джонсона, в этот раз – это ответ на мое электронное сообщение:

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

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

ПРИМЕЧАНИЕ
Дизайн – это постоянный поиск компромиссов. Если мы добавляем гибкость, то мы жертвуем чем-то другим – обычно стоимостью разработки и сопровождения. Аналогично тому, как нет особого смысла заниматься тюнингом производительности приложения на ранних стадиях, нет особого смысла закладывать чрезмерную гибкость каждого разрабатываемого компонента. Именно из-за своих накладных расходов на разработку и сопровождение, оптимизация производительности или гибкости должны производиться лишь тогда, когда мы четко знаем, что это действительно окупится!
Обычно именно простота (помните о разнице
между simple и easy) является наиболее оптимальным фундаментом для будущего улучшения эффективности или изменения функционала.

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

ПРИМЕЧАНИЕ
Аналогично тому, как Мартин Фаулер сдержано относится к AOP, я сдержано отношусь к IoC-контейнерам. Ведь в нашем арсенале есть огромное количество принципов борьбы со сложностью и обеспечения гибкости: неизменяемость и композиция помогает бороться со сложностью, а многие паттерны проектирования упрощают изменения определенных аспектов системы. Чрезмерное выделение интерфейсов (вначале выделим, а потом посмотрим, нужно ли это) делают систему гибкой и слабосвязной ценой увеличения сложности.
Не делайте систему гибкой на всякий случай, делайте ее гибкой там, где это вам действительно необходимо.

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

---------------------------

На этом статья Мартина Фаулера завершается, но я хочу кое-что дополнить.

Лакмусовая бумажка архитектурного решения

Я неоднократно писал о лакмусовой бумажке хорошего дизайна. Когда я рассматриваю дизайн класса или модуля, то стараюсь понять насколько он является цельным и слабосвязным (все те же low coupling и high cohesion) с помощью юнит-тестов. Если их написать невозможно или они будут невменяемыми, то это говорит мне, что с дизайном что-то не то.

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

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

Дополнительные ссылки

P.S. А вы догадались, почему второй вид архитектора называется именно Architectus Oryzus? ;)

7 комментариев:

  1. Сергей, ты только что сделал мою жизнь лучше! Я никогда не задумывался над таким определением архитектуры. Фаулер красавец, а тебе огромное спасибо что донес это мнение до нас! Спасибо!

    ОтветитьУдалить
  2. Статья хорошая. Для 2003 года.

    На мой взгляд, Фаулер «срезает угол» в своих рассуждениях.
    Вместо того, чтобы разобраться в объективной сути архитектуры он опять сваливается в «человеческий фактор» (который, конечно, важен, но не надо путать мух и котлеты) как решение всех проблем.

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

    Непонимание этого приводит Фаулера к парадоксальному «а надо чтоб этой архитектуры вообще не было!». :)
    И к невнятному «архитектурные решения – это все важные. А важные – это про которые эксперт сказал, что они важные».

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

    Если же обратиться к его классификации архитекторов, то я, конечно, соглашусь, что архитектор, который учит команду, при прочих равных лучше того, который все делает сам. Да покажите мне хоть одного человека, кто будет против такого утверждения!
    Весь вопрос в том, что не бывает «прочих равных».

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

    ОтветитьУдалить
    Ответы
    1. А можно ссылку на Ваш доклад?

      Удалить
    2. Фаулер, как и тот же Мартин, и многие другие авторы из нашей области, иногда уходит из объективных критериев оценки некоторого понятия в более эмоциональное или ad hoc-русло.

      Существуют объективные понятия архитектуры, или, например, качества дизайна. Мы можем говорить, что дизайн плох, когда цикломатическая сложность выше N, количество исходящих связей больше К и т.п., а можем сказать так: хороший дизайн легко развивать, понимать и тестировать, а плохой - нет. Первая формулировка (точность которой в моем исполнении тоже равна нулю) может быть более точной, но вторая - хоть и более эмоциональная, может быть более полезной. Гораздо большее число разработчиков смогут провалидировать качество дизайна согласно второму критерию, что, в 90% случаев уже достаточно, чтобы загорелась тревожная лампа в голове и были приняты меры по улучшению дизайна.

      Файлер в своей статье испольлзует тот же самый подход. Он не пытается формализвать понятие архитектуры и архитектора, он пытается дать образ, которому нужно следовать. Кому-то (мне) этот подход кажется полезным, кому-то другому (вам) - он кажется через чур поверхностным. Мозг разных людей устроен по разному, именно поэтому сложно создать универсальное пособие по архитектуре, которое будет подходить каждому: уж очень много индивидуального в этом деле, ИМХО.

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

      Ведь его "пародоксальное а надо, чтобы этой архитектуры вообще не было" - это гипербола, но вполне валидная. Ведь два разных человека могут подходить к дизайну решения по разному. Один постарается изолировать свое решение в минимальном числе модулей, что сделает решение более податливым (supple), в то время, как другой размажет свое решение по десятку классов, сделав свое решение "архитектурным", поскольку изменить его будет невозможно. Вот именно от такой архитектуры предлагает избавляться Фаулер - от accidental architecture, осталяя место лишь essential architecture (если можно так перефразировать высказывания Брукса).

      Старые добрые coupling/cohesion! но как же часто о них забывают:) Вот и получается, что одна команда умеет сводить к минимуму число важных ("архитектурных" по Фаулеру) решений, а другая - нет.

      В общем, ИМХО, подобное неточное описание понятия архитектуры и архитектора - это фича данной статьи, а не баг:)

      З.Ы. Человеческий фактор - ИМХО - отдельная тема, отпишусь чуть позже:)

      Удалить
  3. Короткая версия (с SECR) здесь: https://vimeo.com/110141986
    Режиссерская необрезанная версия: https://vimeo.com/107810012
    Буду благодарен за комментарии и вопросы.

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

    ОтветитьУдалить