- PVSM.RU - https://www.pvsm.ru -
Вашему вниманию предлагается перевод поста Гергелия Ороса, занимающего должность Engineering Manager в Uber. В нем он делится своим взглядом на проектирование крупномасштабных систем, основанном на собственном практическом опыте работы в Uber и Microsoft. В сочетании с комментариями на Hacker News [1], которые добавляют весомые контр-аргументы и дополняют точку зрения автора, его статья стала одним из самых интересных постов недели. В статье используется термин «дизайн кода» для сравнения с традиционной «архитектурой» — о нем подробнее можно прочитать здесь [2].
На мою долю выпало достаточно опыта в проектировании и создании крупномасштабных систем. Я принимал участие в переписывании распределенной системы платежей [3] в Uber, проектировании и релизе Skype на Xbox One и выпуске в открытый доступ RIBs [4] — мобильного архитектурного фреймворка, созданного в Uber. Все эти системы имели тщательно продуманный дизайн, прошли через несколько итераций, с ними связано множество совещаний, проведенных у маркерной доски, и других обсуждений. Затем придуманный дизайн сводился к дизайн-документу, который распространялся среди других разработчиков для сбора дополнительной обратной связи, который продолжался до тех пор, пока мы не переходили к разработке.
Все эти системы отличали большие масштабы: их создавали сотни разработчиков — или они использовали их в своих разработках — и сегодня они бьются в сердцах систем, которыми ежедневно пользуются миллионы людей. Причем, эти проекты создавались не с нуля. Система платежей должна была заменить две другие существующие платежные системы, используемые десятками других систем и дюжинами команд, и все это — без какого-либо ущерба для бизнеса. Переписывание приложения Uber было проектом, над которым одновременно работало несколько сотен инженеров — он включал в себя портирование всей существующей функциональности на новую архитектуру.
Позвольте мне начать с того, что может прозвучать неожиданно. Во-первых, мы никогда не пользовались стандартными средствами планирования архитектуры ПО для работы над дизайнами этих систем. Мы не использовали ни UML [5], ни модель 4+1 [6], ни ADR [7], ни C4 [8], ни диаграммы зависимостей [9]. Мы рисовали множество диаграмм, но ни одна из них не следовала никаким строгим правилам. Нужны были лишь старые добрые прямоугольники и стрелочки — и мы получали диаграммы, похожие на эту, описывающую информационные потоки [10], или другую, изображающую структуру класса и отношения между компонентами [11]. Две диаграммы в одном дизайн-документе часто имели разный стиль, поскольку зачастую они добавлялись или редактировались разными людьми.
Во-вторых, у нас не было архитекторов, которые владели бы дизайном. Не было ни IT Architect [12], ни Enterprise Architect [13]. Это правда — ни в Uber, ни в Skype/Mircrosoft нет штатных позиций для архитекторов ПО. Ожидается, что инженеры высших уровней — например, в должности Staff Engineer — по-прежнему регулярно пишут код. На всех наших проектах есть опытные инженеры — однако, ни один человек не владеет архитектурой или дизайном единолично. В то время, как опытные инженеры являлись движущей силой процесса дизайна, в обсуждение были вовлечены и остальные разработчики, включая даже зеленых «джунов» — причем они часто оспаривали решения других и выносили на обсуждение альтернативные варианты.
В-третьих, мы практически никогда не ссылались на распространенные архитектурные паттерны и другой общепринятый жаргон, который используется в популярной литературе по архитектуре ПО вроде руководства Мартина Фаулера [14]. Не было упоминаний микросервисов, serverless-архитектуры, границ приложений [15], событийно-ориентированной архитектуры (event-driven architecture) и всего остального. Некоторые из этих терминов всплывали во время сессий мозгового штурма; однако, у нас не было никакой необходимости ссылаться на них самих в проектной документации.
Так как же мы со всем справились? И почему мы не стали следовать распространенным подходам к архитектуре ПО?
Я обсуждал этот вопрос с коллегами-инженерами, работающими в других технологические компаниях — как размеров FANG (Facebook, Amazon, Netflix, Google), так и мелких стартапов. Большинство команд и проектов — неважно, были ли они большими или маленькими — объединял схожий подход к дизайну и реализации:
Почему наш подход отличается от того, что обычно упоминается в литературе по архитектуре ПО? На самом деле, наш подход принципиально не так уж сильно отличается от того, что описано в руководствах по архитектуре. Почти все руководства предлагают начинать с бизнес-задачи, а также с описания решений и компромиссов — мы тоже делаем это. Чего мы не делаем — так это не используем более сложные средства, за которые выступают многие архитекторы и книги по архитектуре. Мы документируем дизайн максимально просто, используя для этого самые простые и очевидные инструменты, вроде Google Docs или Office 365.
Я полагаю, что основное различие в нашем подходе сводится к инженерной культуре различных компаний. Высокая степень автономии и сведенная к минимуму иерархия — это черта, которая является общей у современных технологических компаний и стартапов; в случае с более традиционными компаниями, это далеко не всегда справедливо. Также это причина, почему в этих местах чаще прибегают к «дизайну, основанному на здравом смысле» вместо дизайна на основе процесса со строгими правилами.
Мне известны банки и автомобильные компании, где разработчиков активно отговаривают от того, чтобы принимать какие-либо архитектурные решения без того, чтобы подняться вверх по цепочке, получить одобрения от архитекторов на несколько уровней выше, которые наблюдают за несколькими командами. Это делает процесс медленнее, и при большом количестве запросов архитекторы становятся перегруженными. Поэтому эти архитекторы создают еще больше формальных документов, в надежде на то, что система станет более понятной — используя все те инструменты, которые описывает знакомая вам литература. Эти документы подкрепляются подходом «сверху вниз», поскольку он действует на инженеров запугивающим образом — ведь они не архитекторы, и не должны сомневаться или оспаривать решения, ведь они уже были задокументированы при помощи формальных методов, в которых они слабо разбираются. Поэтому они обычно так и не поступают. Честно говоря, эти компании поступают подобным образом для того, чтобы сделать разработчиков взаимозаменяемым ресурсом — ведь это позволяет им перекидывать людей с одного проекта на другой в сжатые сроки. Для вас наверняка не будет сюрпризом то, что для разных окружений лучше подходят различные инструменты.
Целью проектирования системы должна быть простота. Чем проще система, тем проще она для понимания — и тем проще находить в ней проблемы, а также реализовывать ее. Чем яснее язык, которым она описана, тем доступнее ее дизайн. Избегайте пользоваться жаргоном, который не будет понятен каждому члену команды — даже самый неопытный из ваших коллег должен иметь возможность на уровне остальных понимать, о чем идет речь.
Чистый дизайн похож на чистый код: он легко читается и его просто понять. Существует много отличный способов написать чистый код. Однако, вы часто услышите что кто-либо предлагает начать с применения паттернов проектирования «банды четырех» [18] к вашему коду. Чистый код начинается с принципа единственной ответственности, понятных наименований и простых для понимания соглашений. Эти принципы в равной степени применимы к чистой архитектуре.
Так в чем заключается роль архитектурных паттернов? Я нахожу их полезными — настолько же, насколько полезны и паттерны проектирования кода. Они могут подать вам идеи насчет того, как вы можете улучшить свой код или архитектуру. Взять паттерны проектирования кода: я отмечаю для себя, когда замечаю в коде синглтон [19] — и поднимаю брови и копаю глубже, когда я вижу класс, который ведет себя как фасад [20], а на деле всего лишь пробрасывает вызовы. Но еще не наступил тот день, когда я бы подумал «здесь прямо-таки напрашивается абстрактная фабрика [21]». По правде говоря, у меня ушло много времени на то, чтобы понять, что делает этот паттерн и прежде чем меня осенило; понимание пришло в результате плотной работы с инъекцией зависимостей (dependency injection) — одной из немногих областей, где этот паттерн широко распространен и крайне полезен [22]. Я также признаюсь, что пусть я и потратил много времени на чтение и осознание паттернов проектирования «банды четырех», они имели гораздо меньшее влияние на мой профессиональный рост как программиста, чем фидбек, который я получил от других разработчиков относительно своего кода.
Аналогичным образом, знание распространенных архитектурных паттернов — это полезная штука: оно помогает сократить время обсуждений с теми людьми, кто понимает их тем же образом, что и вы. Но архитектурные паттерны не являются целью, и они не станут заменой для более простых вариантов дизайна систем. Когда вы проектируете систему, то можете вдруг осознать, что случайно применили некий распространенный паттерн — и это хорошо, ведь позже вам будет проще сослаться на использованный подход. Но никогда не стоит брать один или несколько паттернов и использовать их в качестве молотка, для которого вам будут везде мерещиться гвозди.
Архитектурные паттерны появились на свет, когда инженеры обратили внимание на то, что в определенных ситуациях имеет смысл принимать схожие решения относительно дизайна и его реализации. Со временем эти решения получили названия, были записаны и обсуждены широкой общественностью. Архитектурные паттерны — это инструменты, которые появились уже после того, как решения были найдены, в надежде на то, что это поможет сделать жизнь остальных проще. Как инженер, вы должны ставить своей целью самостоятельный поиск решений для своих задач и обучаться в ходе этого процесса — вместо того, чтобы брать «хайповый» архитектурный паттерн в надежде на то, что это решит вашу задачу.
У меня часто спрашивают совета: как «прокачаться» в архитектуре и дизайне систем? Опытные инженеры обычно рекомендуют почитать про архитектурные паттерны, а также книги по архитектуре ПО. Я на все сто поддерживаю рекомендацию читать как можно больше — особенно книги, поскольку они позволяют погрузиться в тематику гораздо глубже, чем короткие посты — однако, у меня есть несколько более практических рекомендаций.
Лучший дизайн ПО прост и легок для понимания. В следующий раз, когда вы будете начинать новый проект, вместо того, чтобы размышлять над вопросом "Как я буду проектировать эту систему, какие опробованные в бою паттерны я должен использовать и при помощи какой формальной методологии я должен ее задокументировать?", подумайте — "Как я могу прийти к наипростейшему возможному дизайну — такому, который будет легко понятен любому?".
Лучшие практики архитектуры ПО, архитектурные паттерны корпоративных приложений, формальные способы описания систем — все это инструменты, которыми полезно владеть, поскольку однажды они могут вам очень сильно пригодиться. Но при проектировании систем стоит начинать с простого и продолжать придерживаться максимальной простоты. Старайтесь избегать сложности, которую неизбежно привносят в ваши системы более сложные архитектуры и формальные инструменты.
Данный пост вызвал бурное обсуждение среди работников индустрии, которые поделились своим опытом и отношением к архитектуре ПО. Вы можете ознакомиться с этими дискуссиями на Hacker News [1], Lobste.rs [23] и Reddit [24].
В то время, как большинство комментаторов согласно с основным посылом статьи, другие замечают, что в реальности подобный подход может быть слабо применим к миру «кровавого энтерпрайза», где архитекторы недаром «едят свой хлеб»; они задаются вопросом — как будет выглядеть спроектированная подобным образом система 20 лет спустя и вспоминают «теорию разбитых окон», а также рассказывают про интеграцию 300 IT-систем [25], которая по определнию не может быть простой — ведь каждая из них имеет уникальное API, часть систем работает на Коболе и каждую из них обслуживает от 5000 до 7000 операторов.
Автор: Владимир Маслов
Источник [26]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/330877
Ссылки в тексте:
[1] Hacker News: https://news.ycombinator.com/item?id=21001676
[2] здесь: https://habr.com/ru/post/435386/
[3] распределенной системы платежей: https://habr.com/ru/post/353734/
[4] RIBs: https://github.com/uber/RIBs
[5] UML: https://en.wikipedia.org/wiki/Unified_Modeling_Language
[6] 4+1: https://en.wikipedia.org/wiki/4%2B1_architectural_view_model
[7] ADR: https://github.com/joelparkerhenderson/architecture_decision_record
[8] C4: https://c4model.com/
[9] диаграммы зависимостей: https://herbertograca.com/2019/08/12/documenting-software-architecture/
[10] описывающую информационные потоки: https://eng.uber.com/migrating-functionality-between-production-systems/#attachment_6746
[11] изображающую структуру класса и отношения между компонентами: https://github.com/uber/RIBs/wiki#user-content-parts-of-a-rib
[12] IT Architect: https://martinfowler.com/articles/architect-elevator.html
[13] Enterprise Architect: https://martinfowler.com/articles/ea-in-lean-enterprise.html
[14] руководства Мартина Фаулера: https://martinfowler.com/architecture/
[15] границ приложений: https://martinfowler.com/bliki/ApplicationBoundary.html
[16] Используйте в своём описании понятный и лёгкий язык: https://blog.pragmaticengineer.com/on-writing-well/
[17] мы рассылали все дизайн-документы ПО всем нашим инженерам: https://blog.pragmaticengineer.com/scaling-engineering-teams-via-writing-things-down-rfcs/
[18] паттернов проектирования «банды четырех»: https://en.wikipedia.org/wiki/Design_Patterns
[19] синглтон: https://en.wikipedia.org/wiki/Singleton_pattern
[20] фасад: https://en.wikipedia.org/wiki/Facade_pattern
[21] абстрактная фабрика: https://en.wikipedia.org/wiki/Abstract_factory_pattern
[22] широко распространен и крайне полезен: https://stackoverflow.com/questions/2280170/why-do-we-need-abstract-factory-design-pattern
[23] Lobste.rs: https://lobste.rs/s/n4vihh/software_architecture_is_overrated
[24] Reddit: https://www.reddit.com/r/programming/comments/d5mzcm/software_architecture_is_overrated_clear_and/
[25] рассказывают про интеграцию 300 IT-систем: https://news.ycombinator.com/item?id=21003005
[26] Источник: https://habr.com/ru/post/467997/?utm_source=habrahabr&utm_medium=rss&utm_campaign=467997
Нажмите здесь для печати.