5 принципов архитектуры ПО для старта проекта

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

Привет! Меня зовут Андрей Степанов. Я технический директор в компании fuse8. В своё время, вдохновленный книгой «Принципы» Рэя Далио, я попробовал вывести основные подходы к IT-архитектуре, которые теперь сам активно применяю в работе на старте проектов. О них сегодня и расскажу, чтобы помочь начинающим архитекторам ПО.

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

Но для начала ответим на вопрос — зачем?

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

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

5 принципов архитектуры ПО для старта проекта - 1

Да, у нас есть здание. У него есть стены, окна, двери, балконы и крыша. И в нем даже можно жить. Но сколько это здание простоит? И соответствует ли оно пожеланиям тех, кто будет в нем жить? А что, если из-за архитектурных неточностей строительство в какой-то момент остановится —  в момент, когда станет понятно, что продолжать опасно или дорого. Придется всё снести и начать заново.

Так же и в разработке: вместо удобного и понятного продукта мы получаем что-то, что начнет тормозить, как только зайдут реальные пользователи. А когда вы захотите внести изменения, на это будут уходить человеко-месяцы разработчиков — ведь разобраться в продукте невозможно! Разработчики уволятся, а новые придут и скажут, что надо все переписать. 

На другой стороне спектра — основательные заказчики и архитекторы, которые перед стартом разработки пишут подробнейшее ТЗ. В нем они предусматривают все возможности, продумывают архитектуру вплоть до классов и UML-схем и структур таблицы в БД. Основной риск такого подхода — зависнуть на этапе написания ТЗ и так и не решить бизнес-задачу быстрее конкурентов (вот тут можно почитать, как перестать писать огромные ТЗ и быстрее стартовать разработку).

Саммари

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

Принцип 1: Архитектура подчиняется целям продукта и бизнеса

И никак иначе.

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

Вот вам простой пример. Представьте, что нам нужно сделать обычный блог. А разработчик, увлекшись задачей, начинает внедрять микросервисы, Kafka, Kubernetes и все паттерны, какие может вспомнить, строя мини-космолёт. И вот космолёт есть. Но он никуда не полетит. Потому что нужен был просто блог.

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

Это может быть не так страшно для большой компании, которая может себе позволить дорогие эксперименты, но обернется катастрофой и полным провалом для небольшого бизнеса или стартапа. 

А как надо?

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

5 принципов архитектуры ПО для старта проекта - 2

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

Поэтому: первым делом перед созданием архитектуры стоит изучить текущую продуктовую стратегию или ее аналог.

Но на деле часто мы сталкиваемся с тем, что присутствует лишь смутное видение продукта, а четкой стратегии, для чего и для кого мы это делаем, нет. Возможно всё это «витает в воздухе» или «очевидно», но мы до конца не понимаем. Что делать в этом случае? 

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

Стратегия продукта

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

Цели

Вопросы: Зачем продукт нужен бизнесу? На какие метрики бизнеса он должен повлиять?
Инструменты:
Понимание задачи, Карта влияний

Экономика

Вопросы: Сколько мы готовы потратить на проект? Каким образом он будет зарабатывать или экономить деньги? Сколько он должен заработать, чтобы быть прибыльным? Когда мы должны получить эту прибыль? Каким образом он может принести убытки?
Инструменты: бюджет проекта, Юнит-экономика, Return of investment

Функциональность продукта

Вопросы: Кто и как им будет пользоваться? Какие сценарии или пользователи наиболее важные (или например, прибыльные)? Какие наиболее частые? Что пользователи могут делать в продукте? В каком порядке мы хотим создавать или запускать продукт?

Инструменты: Customer journey mapping, User story mapping, Roadmap 

Мы в своей работе используем многие из этих инструментов на этапе аналитики проекта. 

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

Всё это помогает получить видение продукта и понять, зачем и для чего мы начинаем писать строчки кода.

Саммари

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

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

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

Принцип 2: Архитектура описывает программные системы, их границы и связи

Вроде очевидно, да? Но давайте разберем поглубже.

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

5 принципов архитектуры ПО для старта проекта - 3

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

Что будет, если мы нарушим этот принцип и перестанем следить за границами и связями? Это может повлечь за собой несколько проблем:

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

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

Неявные связи: мы меняем что-то в продукте, и оказывается, что это ломает работу других IT-систем компании.

Вывод: границы и связи, их ограничения – это самое важное. 

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

В ней все просто. Для примера, представим, что мы создаем систему «Агрегатор сервисов доставки»:

5 принципов архитектуры ПО для старта проекта - 4

У нас есть клиенты, которые заказывают доставку, и администраторы, которые следят за качеством работы сервиса. А также другие IT-системы, с которыми сервис должен взаимодействовать. Например, API сторонних сервисов доставки, система бухгалтерского учета и телеграм-бот.

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

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

Саммари

Качественное определение границ подсистем и понимание типов связей — это основа архитектуры.

Принцип 3: Архитектура работает с двумя типами ограничений — железо и люди

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

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

Ограничение первое: железо 

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

Чтобы избежать такой истории мы, как архитекторы, должны всегда думать вот о чем:  

  • Рабочая среда: на каких устройствах и операционных системах будет работать программное обеспечение, каковы их характеристики?

  • Данные: сколько места потребуется для данных и где эти данные будут храниться?

  • Сети:  по каким сетям будут передаваться данные и каково качество этих сетей?

И, поскольку мы живем в физическом мире, в нем всё рано или поздно что-то сломается. Поэтому подумаем сразу и об… 

  • Устранении неполадок: как мы будем справляться с поломками?

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

В таблице ниже представлены примеры фундаментальных ограничений:

5 принципов архитектуры ПО для старта проекта - 5

Ещё одну полезную статью-выжимку об основных показателях задержки для фронтенд-разработчиков написал CTO американской облачной платформы Vercel Малте Убл — Latency numbers every frontend developer should know.

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

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

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

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

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

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

Ограничение второе: люди

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

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

5 принципов архитектуры ПО для старта проекта - 7

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

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

Если сейчас этих людей нет, нужно придумать, как они появятся — мы наймем их, привлечем подрядчиков или найдем еще какой-то способ собрать команду? 

Кто будет работать с архитектурой:

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

Внутренние заказчики и аудиторы. Те люди, которым вы будете сдавать проект. Иногда это CTO, иногда архитектурный комитет, который следит, чтобы архитектура всех продуктов компании следовала общей IT-стратегии.

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

Команда поддержки и развития. Иногда разрабатывает продукт одна команда, а развитием продукта занимается другая.

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

Примеры:

  • Мы создаем продукт небольшой командой опытных сеньор-разработчиков, которые проектировали похожие системы. Дальнейшим развитием будут заниматься они же (например, так работает команда разработки Telegram). 

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

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

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

В архитектуре для людей важно описать: 

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

Разделение большой команды разработки на эти области повысит эффективность работы — разработчики не будут наступать друг другу на пятки. Это то, что в domain-driven design называют bounded context.

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

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

Саммари

Продумывая программную архитектуру, нужно держать в уме два архитектурных ограничения —  «железный» и «для людей»

Если был упущен первый аспект, «для железа», мы получим что-то тормозящее, хрупкое и ненадежное.

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

Принцип 4: Архитектура нужна для роста и изменения продукта в будущем

Тоже довольно очевидно, да? Если бы нам не надо было менять продукт — про архитектуру мы бы не думали.

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

5 принципов архитектуры ПО для старта проекта - 8

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

Саммари

Скорость адаптации программного продукта к планируемым или желаемым изменениям – это критерий качества ИТ-архитектуры.

Даже если мы разрабатываем продукт, который не планируем дальше активно развивать (например сайт компании, который дальше будет просто наполняться контентом 3-5 лет без изменений функциональности) — мы как минимум должны иметь план архитектуры на время разработки.

Принцип 5. Архитектура ПО может эволюционировать вместе с продуктом. 

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

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

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

Разработчики продукта постоянно что-то «садят» — массы кода появляются, начинают разрастаться, где-то затухают и загнивают. А мы, как садоводы, пытаемся это все организовать в единое целое. 

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

По факту, с такой концепцией получается, что у нас достаточно широкая, в отличии от строительных архитекторов, и более гибкая область действий.

5 принципов архитектуры ПО для старта проекта - 9

Получается, что ответ на вопрос «Как сделать так, чтобы не переделывать» – никак. И вообще, это неправильный вопрос. Правильный вопрос – «Как сделать так, чтобы не пришлось переделывать в ближайшие N месяцев»

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

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

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

Принцип 6: Самоописываемость кода и архитектуры

Если кратко, иногда проще написать код, чем нарисовать диаграмму.

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

Хороший код — самоописываемый. Читая его, можно легко понять, что же делает продукт. Почему бы не воспользоваться этим замечательным свойством?

Примеры:

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

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

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

Автогенерация документации по коду. Вот несколько примеров: 

  • Самый частый пример  — документация для API, их запросов, параметров и форматов данных. 

  • Для REST API разработчики пишут код бекенда, затем на его основе автоматически генерируется спецификация в формате OpenAPI и документация в виде Swagger UI. Аналогичные инструменты есть для AsyncAPI, gRPC. 

  • ER диаграммы по коду БД. Они могут быть довольно наглядными, особенно если сначала таблицы сгруппировать вручную. 

Интерактивная документация по БД, сгенерированная через Liam ERD

Интерактивная документация по БД, сгенерированная через Liam ERD

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

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

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

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

Заключение

Если вы оттолкнетесь от принципов, перечисленных в статье, ваша архитектура перестанет быть произвольной, переусложненной, недостаточной. 

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

Это непростая задача, но при должном внимании и терпении у вас обязательно все получится! Удачи!


Иллюстрации в статье: MChe Lee и Jan Canty, Сайт «История Москвы»,      

Автор: andrey_stepanov1

Источник

Оставить комментарий