Большой комок грязи

в 6:52, , рубрики: Анализ и проектирование систем, антипаттерны, архитектура приложений, Проектирование и рефакторинг, управление разработкой

Привет! Представляю вашему вниманию перевод статьи "Big Ball of Mud" авторов Brian Foote и Joseph Yoder.

От переводчика: Статья Big Ball of Mud написана Брайаном Футе и Джозефом Йодером летом 1999 года. Она рассказывает о наиболее распространённых антипаттернах разработки ПО, причине их возникновения и развития. Несмотря на то, что с момента публикации прошло больше 18 лет, описанные проблемы никуда не пропали, так что большая часть написанного актуальна и по сей день. Это первая часть статьи из трёх, остальные я надеюсь выложить в ближайшее время.

Введение

В последние годы сразу несколько авторов [Garlan и Shaw, 1993] [Shaw, 1996] [Buschmann и другие, 1996] [Meszaros, 1997] представили паттерны, которые характеризуют архитектуру ПО высокого уровня, например, PIPELINE (конвейер) и LAYERED ARCHITECTURE (многоуровневая архитектура).

В идеальном мире все системы были бы образцом одного или более подобных шаблонов высокого уровня. Тем не менее, в реальной жизни все не так. Архитектура, которая на данный момент является доминирующий, до сегодняшнего дня ещё не обсуждалась. Речь идет о BIG BALL OF MUD или БОЛЬШОМ КОМКЕ ГРЯЗИ.

БОЛЬШОЙ КОМОК ГРЯЗИ имеет небрежно разработанную структуру, он беспорядочный, сырой, словно перемотанный на скорую руку изоляционной лентой и проводами, запутавшийся в джунглях спагетти-код. Мы все видели такой код. В этих системах легко найти признаки нерегулируемого роста и постоянных доделок. Информация распространяется без разбора между отдаленными элементами системы, при этом зачастую вся важная информация становится глобальной или дублируется. Структура системы в целом никогда не было точно определена. Если и была, то ее разрушили до такой степени, что оригинал уже не узнать. Программисты хоть немного понимающие архитектуру, обходят это болото стороной. И только те, кого она волнует мало и, возможно, те, кому нравится латать дыры в системе каждый день, довольны работой таких систем.

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

В этой статье мы представляем следующие семь паттернов:

  • BIG BALL OF MUD (БОЛЬШОЙ КОМОК ГРЯЗИ)
  • THROWAWAY CODE (РАЗОВЫЙ КОД)
  • PIECEMEAL GROWTH (ПОЭТАПНЫЙ РОСТ)
  • KEEP IT WORKING (ПУСТЬ РАБОТАЕТ)
  • SHEARING LAYERS (СДВИНУТЫЕ СЛОИ)
  • SWEEPING IT UNDER THE RUG (ЗАМЕСТИ ПОД ПОЛОВИК)
  • RECONSTRUCTION (РЕКОНСТРУКЦИЯ)

Почему система превращается в БОЛЬШОЙ КОМОК ГРЯЗИ? Иногда большие и страшные системы появляются из-за создания разового кода (THROWAWAY CODE). Разовый код – это быстрый, черновой вариант кода, который должен был использоваться только один раз, а затем выброшен. Однако иногда такой код начинает жить собственной жизнью, несмотря на свою не проработанную структуру и плохо разработанную документацию или ее отсутствие. Он работает, зачем что-то чинить? Когда возникает какая-то проблема, то самый быстрый способ решить ее — изменить работающий код. Это избавляет от необходимости создавать программу с нуля, но со временем, простые разовые программы порождают БОЛЬШОЙ КОМОК ГРЯЗИ.

Даже системы с хорошо прописанной архитектурой рискуют пострадать от распада структуры. Любая успешная система находится под огнём постоянно изменяющихся требований, что постепенно подрывает ее структуру. Некогда чистые системы зарастают из-за поэтапного роста структуры (PIECEMEAL GROWTH), и элементы системы начинают разрастаться бесконтрольно.
Если не прекратить этот рост, то структура системы нарушается до такой степени, что от нее нужно отказываться. Как в случае с районами города, которые приходят в упадок, эта ситуация усугубляется по нарастающей. Так как понимание системы становится все труднее, ее поддержка становится сложнее и обходится все дороже. Хорошие программисты отказываются работать с такой структурой. Инвесторы выводят свой капитал. И всё же можно провести ещё одно сравнение с городскими районами: есть способы избежать и даже обратить вспять этот упадок. Как и все в нашем мире, противодействующие энтропические силы требуют вложения энергии. Джентрификация программного обеспечения — не исключение. Один из способов остановить энтропию в ПО — перепроектирование (рефракторинг). Приверженность периодическому рефакторингу может защитить систему от сползания в БОЛЬШОЙ КОМОК ГРЯЗИ.

Серьезное наводнение, пожар или военные действия могут вызвать необходимость эвакуации жителей и восстановления города с нуля. Чаще всего, изменения затрагивают отдельные здания или район, а сам город продолжает функционировать. Однажды установленная, стратегия «пусть работает» (KEEPING IT WORKING) сохраняет жизнь города, пока он снова растет и развивается.

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

Простой способ начать контролировать упадок — оградить районы трущоб и поставить вокруг них красивый фасад. Мы называем эту стратегию «ЗАМЕСТИ ПОД ПОЛОВИК» (SWEEPING IT UNDER THE RUG). В более серьезных случаях, трудно найти альтернативу, поэтому все сносят и начинают строительство заново, с чистого листа. Когда требуется полная реконструкция (RECONSTRUCTION), то все, что остается спасти — это лежащие в основе паттерны.

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

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

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

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

Паттерны, которые мы описываем здесь, не будут рассматриваться отдельно друг от друга. Мы объединили их в единый контекст, в котором также присутствуют другие описанные нами и другими авторами паттерны. В частности, мы проводим сопоставление с паттернами жизненного цикла, фазой прототипирования (PROTOTYPE PHASE), фазой расширения (EXPANSIONARY PHASE) и фазой консолидации (CONSOLIDATION PHASE), описанными в работах [Foote и Opdyke, 1995] и [Coplien, 1995]; а также, сравниваем с паттерном тектоники ПО (SOFTWARE TECTONICS) [Foote и Yoder, 1996] и паттернами разработки структуры [Roberts и Johnson, 1998].

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

Силы

Многие силы способствуют тому, что даже организации с аккуратной архитектурой начинают создавать БОЛЬШИЕ КОМКИ ГРЯЗИ. Эти повсеместные, «глобальные» силы влияют на все указанные ранее паттерны. Среди таких сил выделим следующие:

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

Одной из причин, почему архитектура программного обеспечения зачастую столь посредственная заключается в том, что она уступает место текущим проблемам, таким как затраты, срок от идеи до внедрения, навыки программиста. Архитектуру часто считают роскошью или бесполезным излишеством. Архитектуру нередко игнорируют и даже относятся к ней с некоторым пренебрежением. Конечно, плохо, что выработалось такое отношение к архитектуре, но это можно понять. Архитектура — область, которая требует длительного внимания. Если мы хотим, чтобы разрабатываемый продукт был успешный и перспективный, то, в первую очередь, нужно заниматься более насущными вопросами, о которых мы написали выше. А преимущества хорошей архитектуры появляются на более поздних этапах жизненного цикла, когда продукт уже полностью сформирован, и появляются повторно используемые компоненты[Foot и Opdyke, 1995].

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

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

Затраты: архитектура — это дорого, особенно, когда изучается новая область. Разработка правильный архитектуры кажется бессмысленной роскошью, если система и так работает. Инвестиции в её разработку обычно не оправдывают себя сразу же. К тому же, она может привести к длительной задержке вывода продукта на рынок. Кто получает преимущества от инвестиций в архитектуру и когда можно ожидать возврат на инвестиции? Деньги на быстрые и «сырые» проекты, которые сразу же можно вывести на рынок, тратятся с большей готовностью. Деньги же на разработку и анализ сложной архитектуры инвестируют с меньшим желанием. Трудно окупать свои затраты на архитектурные активы, когда вы уже давно обанкротились.

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

Опыт: даже, когда у человека есть время и желание заняться вопросами архитектуры, его опыт или отсутствие опыта работы в конкретной области могут ограничить те архитектурные сложности, которые можно было бы внедрить в систему, особенно на ранней стадии развития системы. Некоторые программисты преуспевают в той среде, где они могут открывать и развивать новые абстракции, в то время как другие программисты предпочитают комфортную работу в более ограниченной среде (например, Smalltalk vs. Visual Basic). Часто начальные версии системы являются своего рода экспериментальным средством, при помощи которого программисты пробуют внедрять различные элементы, чтобы решить конкретную проблему. И только когда проблемы и их решения будут найдены, среди этих внедренных элементов начинают появляться архитектурные границы. Неопытность может принимать разные формы. Есть абсолютная неопытность выпускника школы. У хорошего архитектора может отсутствовать опыт работы в той или иной области или эксперт в конкретной области, который в совершенстве знает код, может не иметь опыта разработки архитектуры.

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

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

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

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

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

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

Сложность: одна из причин появления «грязной» архитектуры заключается в том, что программное обеспечение часто отражает сложность области, в которой работает приложение. Brooks придумал этому явлению термин «неотъемлемая сложность» [Brooks, 1995]. Другими словами, программное обеспечение становиться сложным и непонятным, потому что сама проблема тоже не понятна или, по крайней мере, понята не до конца. Нередко организация системы отражает историю организации, которая и создала эту систему (согласно ЗАКОНУ КОНВЕЯ [Coplien, 1995]). Пересмотреть сложившиеся отношения зачастую бывает трудно, так как уже сложились базовые границы среди элементов системы. Эти отношения могут приобрести характер границы «района», что наблюдается в реальных городах [Brand, 1994]. Возникают большие проблемы, когда приложению требуется свободное взаимодействие за пределами этих границ. Система превращается в спутанный клубок, и даже остатки структура, которые были там изначально, начинает все больше разрушаться.

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

Масштаб: управление крупными проектами — это качественно иная проблема, в отличие от работы с малыми проектами. Это как вывести целую дивизию пехотных войск в бой и командовать небольшим отрядом войск специального назначения. «Разделяй и властвуй» — это, по сути, необходимое, но недостаточное решение проблем, вызванных масштабом. Алан Кей (Alan Kay) во время своего выступления на OOPSLA '86 заметил, что «хорошие идеи не всегда масштабируются». Это наблюдение вызвало реакцию Генри Либермана, который спросил: «то есть, нам остается масштабировать плохие идеи?»

БОЛЬШОЙ КОМОК ГРЯЗИ

он же
ТРУЩОБЫ
СПАГЕТТИ-КОД

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

Дома в трущобах обычно строят из простых, недорогих материалов, используя самые простые инструменты. Трущобы можно построить, используя сравнительно малоквалифицированный труд. И хотя в привычном понимании трудовая сила будет «малоквалифицированная», строительство и содержание зданий в трущобах будет трудоемким процессом. Специализации практически не требуется. Дом строят и ремонтирую, преимущественно, сами жители. В трущобах не заботятся об инфраструктуре, так как инфраструктура требует координации действий и вложений капитала, особых ресурсов, специального оборудования и навыков. Планирование или контроль роста трущоб тоже практически отсутствует. Трущобы появляются там, где есть необходимость в строительстве жилья, переизбыток неквалифицированной рабочей силы и недостаток вложений капитала. Они удовлетворяют сиюминутную локальную потребность в жилье, привлекая доступные ресурсы, чтобы решить проблему. Более сложные архитектурные подходы — это роскошь, которая может подождать.

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

Когда приближается завершение разработки системы, с ней впервые могут начать работать фактические пользователи. Этот опыт может вдохновить на изменения формата данных и пользовательского интерфейса, что снова отрицательно сказывается на архитектурных решениях, хотя все думали, что с архитектурой все улажено. Также, как отмечает Brooks [Brooks, 1995], так как программное обеспечение такое гибкое, оно часто несет на себе бремя архитектурных компромиссов на поздней стадии цикла развития документации программного обеспечения/аппаратных средств, именно из-за этой гибкости.

Этот феномен не уникален и встречается не только в ПО. Stewart Brand [Brand, 1994] заметил, что период до того, как здание будет заселено первыми жильцами, является самым напряженным как для архитекторов, так и для клиентов. Деньги кончаются, а осталось доделать именно те части здания, с которыми жильцы будут чаще всего сталкиваться. В этот период становится очевидным, что некоторые пункты из списка желаемых вещей не получается выполнить, а различные экзотические эксперименты не будут работать. Поэтому выполнение самого важного на данный момент становится компромиссным решением.

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

Необходимо предоставить качественное ПО вовремя и уложиться в бюджет.

Затраты: Архитектура — это долгосрочная инвестиция. Люди, которые оплачивают счета, обычно пренебрегают этим, только если они сразу не получат осязаемую выгоду, например, списание налогов; или если не будет дополнительной прибыли или больше времени. Однако такое случается редко. Чаще всего клиент хочет получить продукт, который уже завтра будет на него работать. Как правило, люди, которые контролируют и управляют процессом разработки просто не рассматривают архитектуру, как неотложную проблему. Если программисты знают, что их усилия и профессионализм останутся без внимания, а менеджеры все равно не хотят платить за хорошую работу, рождается порочный круг.

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

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

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

Следовательно, акцент сначала делается на свойствах и функциональных возможностях, затем на архитектуре и эффективности.

Описанная ситуация напоминает аргументы Габриэля (Gabriel) «Чем хуже, тем лучше» [Gabriel, 1991]. Почему так много ПО превращается в БОЛЬШОЙ КОМОК ГРЯЗИ, несмотря на самые лучшие намерения и усилия разработчиков? Почему тактика «выжигания и посадки» вытесняет изящное ПО? Плохая архитектура действительно вытесняет хорошую?

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

Есть те, кто толкуют это ситуацию с точки зрения подхода на основе концепции доски объявлений [Buschman, 1996], но, на самом деле, она больше напоминает сборную солянку. Там, где информация о состоянии классифицирована, она может быть передана в случайном порядке через потайные ходы, которые обходят исходную структуру системы.

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

БОЛЬШОЙ КОМОК ГРЯЗИ можно считать анти-паттерном, так как мы ставим перед собой задачу показать, как пассивность перед силами, которые негативно сказываются на архитектуре, может привести к болоту. Однако неоспоримая популярность этого паттерна заставляет нас сделать вывод, что это самостоятельный паттерн. Это повсеместное, повторяющееся решение проблемы создания рабочей системы в контексте разработки ПО. Может показаться, что это путь наименьшего сопротивления, когда разработчик противостоит силам, которые мы обсуждали выше. И только поняв логику привлекательности паттерна, мы можем направить или нейтрализовать силы, приводящие к БОЛЬШОМУ КОМКУ ГРЯЗИ.

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

Кент Бек (Kent Beck) описал такой путь создания программного обеспечения: Сделать рабочим. Сделать правильно. Сделать быстро. [Beck, 1997]. «Сделать рабочим» означает, что сперва мы должны сконцентрироваться на функциональности и сделать так, чтобы наш продукт запустился. «Сделать правильно» означает, что мы должны задуматься о структуре системы, только после того как мы определим, что нам нужно, чтобы решить проблему. «Сделать быстро» означает, что мы должны позаботиться об оптимизации ПО, только после того как мы узнаем, как решить проблему и определим архитектуру, которая изящно впишется в функциональность. Когда все эти условия будут выполнены, можно подумать о том, как сделать это дешевле.

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

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

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

Наконец, у всех инженеров разный уровень навыков и опыт работы с архитектурой. К сожалению, архитектура долгое время оставалась недооцененной, поэтому многие инженеры воспринимают БОЛЬШОЙ КОМОК ГРЯЗИ, как норму. Действительно, некоторые инженеры обладают особенно хорошими навыками пробираться сквозь хаос и показывать дорогу другим. Со временем, этот симбиоз между архитектурой и навыками может изменить характер организации, так как гиды по этому хаосу станут более ценными, чем архитекторы. Согласно ЗАКОНУ КОНВЕЯ [Coplien, 1995], архитекторы будут исключены за ненужностью, а инженеры, которые отточили свои навыки работы с грязными системами будут востребованы. [Foote и Yoder, 1998a] зашли еще дальше и заявили, что малопонятный код может даже иметь преимущество над хорошим кодом, просто потому что его трудно понять и изменить. Это преимущество может распространиться на программистов, которые способны разобраться в таком коде. Такие специалисты могут оказаться незаменимыми.

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

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

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

Статус программиста в «вертикали власти» часто зарабатывается проявлением ума, а не простотой и ясностью, выполненной на высоком уровне.

И тем не менее, можно говорить о том, что случайная, недифференцированная структура БОЛЬШОГО КОМКА ГРЯЗИ — это одно из секретных преимуществ, так как мы напрямую можем обратиться к силам, действующим между двумя частями системы, не влияя на архитектурные устремления. В типичном КОМКЕ ГРЯЗИ, эти устремления, в лучшем случае, будут довольно скромными. Случайный подход к архитектуре характерен для ранних этапов развития системы, так как программисты, архитекторы и пользователи еще пока учатся работать в этой области [Foote и Opdyke, 1995]. Во время фазы прототипирования (PROTOTYPE) и расширения (EXPANSION) типичен прием наследования кода и расслабленный подход к инкапсуляции. Позже, когда нарабатывается опыт работы с системой, архитектурный домен становится более различим, и появляются компоненты более надёжного “черного ящика”. Другими словами, если в начале система выглядит как БОЛЬШОЙ КОМОК ГРЯЗИ, то это нормально, по крайней мере, пока вы не узнаете ее получше.

Брайан Марик (Brian Marick) впервые предложил название BIG BALL OF MUD (большой комок грязи) для описания подобной архитектуры. Несколько лет назад, во время выступления в дискуссионной группе на тему паттернов в университете Иллинойса он также отметил, что это, вероятно, доминирующий типа архитектуры. С тех пор, мы также применяем этот термин. Само по себе название появилось в 1970-х для характеристики семейства языков Лисп (Lisp).
Архитектура по типу БОЛЬШОГО КОМКА ГРЯЗИ часто появляется из разовых прототипов или РАЗОВОГО КОДА (THROWAWAY CODE), потому что прототип или сохраняется, или от разового кода так никогда никто не избавляется (можно назвать это «маленькими комками грязи»).

Также подобная архитектура может появится в ходе постепенного обслуживания и ее поэтапный рост (PIECEMEAL GROWTH) влияет на структуру зрелой системы. Как только система признана рабочей, оптимальный способ сохранять рост — использовать принцип «пусть работает» (KEEP IT WORKING). Когда сдвинутые слои (SHEARING LAYERS), которые появляются в ответ на изменения и дальнейшее развитие системы, сталкиваются с существующей структурой системы, это может привести к развитию большого комка грязи (BIG BALL OF MUD).

Паттерны прототипирования и расширения [Foote и Opdyke, 1995] подчеркивают, что период исследований и экспериментов оказывается наиболее полезным, до того как начнется работа над архитектурой.

Однако все эти действия, которые могут повлиять на структуру системы, должны быть вплетены в фазу консолидации (CONSOLIDATION PHASES) [Foote и Opdyke, 1995], во время которой используются возможности провести рефакторинг системы для укрепления ее структуры. Сторонники экстремального программирования (Extreme Programming) [Beck, 2000] также выступают за непрерывное написание кода и рефакторинг.

[Brand, 1994] заметил, что здания с большим пространство, украшенные обычными колоннами обладают парадоксальным эффектом, а именно они способствуют инновационному повторному использованию пространства как раз, потому что колонны ограничивают созданное пространство. Грандиозные полеты архитектурной мысли были невозможны, что сокращало количество возможных альтернатив. Иногда свобода от выбора (FREEDOM FROM CHOICE) [Foote, 1988] — это именно то, что нам на самом деле нужно.

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

Еще одна техника экстремального программирования — это парное программирование [Beck, 2000]. В чистом виде, парное программирование означает, что каждая написанная строка кода добавляется в систему двумя программистами. Один печатает код, а другой непрерывно просматривает всю картину. В отличие от традиционного метода разработки программного обеспечения в одиночку, при парном программировании код проходит очень тщательную проверку.

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

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

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

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

Со времен римского архитектора Марка Витрувия [Vitruvius, 20 до н.э.], архитекторы придерживаются знаменитой триады Витрувия: firmitas (прочность конструкции), utilitas (польза), venustas (красота). Большой комок грязи обычно отражает триумф пользы над красотой. Прочностью тоже можно пожертвовать, потому что непонятная программы сводит на нет и без того тщетные попытки ее обслуживания. Феномен разбухания наблюдается во многих крупных потребительских программных продуктах, что в очередной раз доказывает, что дизайнеры решили заняться исключительно утилитарными задачами, зачастую в ущерб архитектуре и качеству.

Оригинал статьи

Автор: Arkronus

Источник

Поделиться

* - обязательные к заполнению поля