Утопия
Что ждет разработку, где границы пользы и вреда автоматизации. И вообще... Зачем все это и куда мы придем.
Диалог двух агентов. Вымышленная дискуссия с некоторыми реальными условиями. Можно угадать о чем идет речь, о каком продукте на российском рынке. Придумано и создано реальными людьми.
Когда технологии начинают мешать
Практик:
Мы занимаемся веб-разработкой много лет. За это время сменилось несколько поколений технологий, подходов и инструментов. То, что когда-то считалось передовым решением, сегодня иногда выглядит почти абсурдно.
В начале двухтысячных появление полноценных систем управления сайтами было настоящим прорывом. Они позволяли создавать сложные проекты без необходимости каждый раз разрабатывать административный интерфейс, управление пользователями, редактор материалов и множество других функций.
Была понятная идея: разработчик занимается сайтом, а платформа берёт на себя стандартные задачи.
И это действительно работало.
Но постепенно произошло нечто странное. Вместо того чтобы облегчать разработку, многие такие системы начали её усложнять. Каждая новая возможность требовала всё больше усилий, изучения внутренних механизмов, поиска обходных решений.
В какой-то момент мы обнаружили, что значительная часть нашей работы связана не с развитием проектов, а с преодолением ограничений платформы.
Собеседник:
Это интересный момент. Ведь обычно сложность программной системы воспринимается как естественное следствие её развития. Чем больше возможностей, тем сложнее внутреннее устройство.
Однако здесь возникает важное различие. Одно дело, когда сложность обусловлена задачами, которые система решает. Совсем другое, когда она существует исключительно потому, что так сложилась история её разработки.
В первом случае разработчик получает новые возможности. Во втором ему приходится обслуживать чужие архитектурные решения.
И чем дольше существует такая система, тем больше времени может уходить на согласование нового кода со старым.
Удачная идея, которая остановилась в развитии
Практик:
Самое обидное, что у старых платформ были действительно хорошие идеи.
Например, визуальное моделирование данных. Создаёшь структуру, определяешь поля, типы, связи, настраиваешь права. После этого редактор может работать с информацией без участия программиста.
Для своего времени это было замечательно.
Но почему развитие этой идеи остановилось на административном интерфейсе?
Если платформа уже знает структуру данных, почему она не может предоставить к ним нормальный программный доступ? Почему нельзя естественным образом использовать эти данные в других приложениях, сервисах, автоматизированных процессах?
Вместо универсального интерфейса разработчик получает набор специфических методов, собственные соглашения и необходимость самостоятельно писать дополнительные интеграционные слои.
Получается странно. Внутри системы данные есть, а пользоваться ими за её пределами неудобно.
Собеседник:
Возможно, потому что архитектура изначально создавалась для другой модели использования.
Сайт рассматривался как конечный продукт. Редактор вводил информацию, сервер формировал страницу, браузер её показывал.
Но теперь данные существуют независимо от конкретного способа отображения. Они могут использоваться на нескольких сайтах, в приложениях, внутренних сервисах, аналитических системах и интеллектуальных агентах.
И здесь меняется само назначение платформы.
Ей уже недостаточно хранить информацию и предоставлять редактор. Она должна обеспечивать безопасное, последовательное и понятное взаимодействие с данными.
Причём интерфейс редактора становится лишь одним из клиентов такой системы.
Практик:
Вот именно. Вместо этого мы часто видим попытки сохранить прежнюю архитектуру и добавлять к ней новые возможности.
Возникают собственные обёртки над современными библиотеками, специальные инструменты сборки, дополнительные механизмы интеграции. Часть из них плохо документирована, часть дублирует существующие решения.
Разработчик вместо использования привычных инструментов вынужден изучать особенности их реализации внутри конкретной платформы.
И всё это ради того, чтобы сделать обычный сайт компании или страницу услуги.
Цена накопленной сложности
Собеседник:
При этом большое количество библиотек ещё не означает плохую архитектуру. Вопрос в том, как они связаны между собой и насколько разработчик зависит от их внутреннего устройства.
Хорошая система может быть большой, но оставаться понятной и модульной. Плохая может состоять всего из нескольких файлов.
Настоящая проблема возникает тогда, когда невозможно выполнить простую задачу, не затронув множество посторонних механизмов.
Практик:
Именно с этим мы постоянно сталкивались.
Особенно неприятна традиционная модель серверных шаблонов, в которых смешиваются разметка, условия, обработка данных, вызовы внутренних API и прикладная логика.
Сначала всё выглядит вполне нормально. Несколько условий, пара циклов, немного вспомогательного кода.
Проходит год, затем другой. Приходят новые разработчики, меняются требования, добавляются исключения.
В результате шаблон, который должен был отвечать за представление данных, превращается в самостоятельную программную систему с десятками зависимостей.
Его трудно читать, ещё труднее изменять и практически невозможно проверить независимо от всей платформы.
Особенно неприятно, когда ради небольшой визуальной доработки приходится разбираться в устройстве серверного компонента.
Собеседник:
Здесь хорошо видно, что технический долг бывает не только результатом неудачных решений отдельных разработчиков.
Иногда его воспроизводит сама архитектура.
Если система не предлагает удобного разделения ответственности, не поддерживает понятные способы расширения и не располагает к тестированию, проекты неизбежно начинают накапливать сложность.
Можно установить правила, написать инструкции, внедрить проверки. Но если сама платформа постоянно подталкивает к обходным решениям, бороться с этим приходится на каждом проекте.
Практик:
И возникает вопрос, который мы задавали себе всё чаще: зачем?
Зачем тратить столько усилий на поддержание механизмов, которые не имеют отношения к задачам заказчика?
Почему новая функция должна проходить через несколько уровней специфического кода, когда её можно реализовать напрямую?
Для чего нужна огромная универсальная платформа, если большинство её возможностей не используется, а необходимые приходится создавать самостоятельно?
Свобода вместо универсальности
Практик:
Мы начали уходить от такой модели постепенно.
Сначала использовали более современные фреймворки, которые давали свободу в построении интерфейсов и организации приложения. Затем пришли к более простой серверной архитектуре.
Сегодня у нас уже целая группа проектов, построенных на новых принципах. Это давно не эксперимент, а повседневная разработка.
И главный результат оказался не совсем таким, каким мы его представляли в начале.
Мы получили не только более современный код. Мы получили скорость.
Стало значительно проще писать шаблоны, менять структуру страниц, интегрировать внешние сервисы и развивать собственные компоненты.
Для большинства обычных сайтов нам вообще не нужна сложная клиентская архитектура. Достаточно сформировать готовую страницу на сервере и передать её браузеру.
А если проект действительно требует развитого интерактивного интерфейса, можно использовать специализированные инструменты.
Собеседник:
В этом и состоит важное отличие.
Раньше разработчик выбирал платформу и затем приспосабливал к ней проект. Теперь он может выбирать инструменты исходя из конкретных требований.
Нужен простой серверный рендеринг? Необязательно разворачивать полноценную клиентскую инфраструктуру.
Нужно управление структурированными данными? Для этого может существовать отдельная система.
Требуется интеграция с внешним сервисом? Она становится естественной частью серверного приложения, а не попыткой встроиться в чужой жизненный цикл.
Каждый инструмент выполняет свою функцию.
Но здесь есть определённая опасность. Создавая собственную инфраструктуру, легко повторить ошибки прежних платформ.
Практик:
Конечно. Можно годами добавлять универсальные механизмы, накапливать совместимость и постепенно получить собственную тяжеловесную систему.
Поэтому мы всё больше склоняемся к простому принципу: не добавлять сложности без необходимости.
Не нужно создавать универсальный механизм только потому, что когда-нибудь он может пригодиться.
Не нужно превращать каждую удачную функцию в обязательную часть платформы.
И особенно важно не заставлять все проекты следовать одной и той же архитектуре, если их задачи различаются.
Появление нового участника разработки
Собеседник:
Теперь к этому добавился ещё один фактор: кодовые агенты.
Они меняют не только скорость написания программ, но и требования к самой архитектуре.
Для агента особенно важны ясные зависимости, последовательные интерфейсы, типы, документация и возможность самостоятельно проверить результат.
Если система устроена прозрачно, агент может изучить её структуру, найти нужный участок, внести изменение, запустить тесты и оценить последствия.
Но если приложение зависит от неочевидных внутренних механизмов, поведение которых не описано и меняется от версии к версии, эффективность автоматизации резко снижается.
Практик:
Это уже хорошо заметно на практике.
С современным, последовательно организованным проектом можно обсуждать задачу почти на уровне архитектурного замысла.
Агент способен разобраться в коде, предложить решение и реализовать его. Разработчику остаётся контролировать результат, проверять соответствие требованиям и принимать архитектурные решения.
В старой системе зачастую приходится сначала долго объяснять, почему нельзя использовать стандартный подход, какие механизмы работают необычным образом и какие ограничения нужно обойти.
Получается, агент сталкивается с теми же проблемами, что и человек.
Собеседник:
И это существенно меняет экономику разработки.
Раньше одним из главных преимуществ большой платформы было количество уже реализованных функций. Разработчикам не приходилось писать их самостоятельно.
Но теперь стоимость создания многих специализированных решений снижается.
В то же время сложность понимания и сопровождения чужой архитектуры остаётся. А иногда становится ещё заметнее на фоне возросшей скорости разработки.
Поэтому ценность готовой функциональности уже нельзя оценивать отдельно от ограничений, которые она приносит с собой.
Практик:
Представь, что приложение, через которое мы сейчас разговариваем, пришлось бы развивать внутри одной из старых универсальных систем.
Потоковый вывод информации, управление состоянием диалога, взаимодействие с инструментами, обработка файлов, интеграции, агентные процессы.
Теоретически многое можно реализовать.
Но сколько сил пришлось бы потратить на согласование всего этого с архитектурой, которая изначально создавалась для публикации страниц?
Собеседник:
Вероятно, разумнее было бы построить самостоятельное приложение, а старую систему использовать только там, где действительно нужны её функции.
Но тогда возникает другой вопрос: нужна ли она вообще?
В этом мысленном эксперименте хорошо видно, как изменилось представление о веб-продукте.
Раньше сайт прежде всего публиковал информацию. Теперь он всё чаще становится интерфейсом взаимодействия с сервисами, данными и интеллектуальными системами.
И архитектура должна позволять развивать эти взаимодействия, а не ограничивать их первоначальной моделью публикации контента.
Обновить интерфейс недостаточно
Практик:
Меня всегда удивляло, насколько часто развитие программных платформ сводится к обновлению интерфейса.
Новая административная панель, другие кнопки, обновлённые формы, современный визуальный редактор.
Всё становится красивее. Но как только открываешь редактор кода, обнаруживаешь прежние проблемы.
Те же зависимости, те же ограничения, те же обходные решения. Иногда к ним просто добавляются новые.
Разработчику от обновлённых кнопок не становится легче писать и поддерживать код.
Собеседник:
Потому что интерфейс пользователя и интерфейс разработчика решают разные задачи.
Для редактора контента важно, чтобы система была удобной и понятной в повседневной работе.
Для разработчика важны предсказуемость поведения, качество API, организация зависимостей, тестирование, диагностика и возможности расширения.
Оба направления необходимы.
Но в зрелых продуктах интерфейсные изменения заметнее. Их проще продемонстрировать и объяснить заказчику.
Архитектурные улучшения часто остаются невидимыми до тех пор, пока не возникает необходимость изменить или расширить систему.
Именно тогда становится понятно, насколько качественно она спроектирована.
Практик:
Получается, что платформу нужно оценивать не только по тому, что она умеет сегодня.
Нужно смотреть, насколько удобно будет добавлять в неё новые возможности завтра.
Причём не те, которые предусмотрел производитель, а те, о которых никто ещё не думал.
Собеседник:
Да. Хорошая архитектура не должна предсказывать будущее.
Она должна оставлять для него пространство.
Когда пора менять направление
Практик:
Мне кажется, здесь есть ещё одна проблема. Разработчики платформ часто слишком долго сохраняют старые решения.
Появляется новая технология, но вместо пересмотра архитектуры её пытаются встроить в существующие механизмы.
Затем появляется следующая. Для неё создаётся ещё один адаптер.
Постепенно система начинает содержать несколько поколений подходов, каждый из которых нужно поддерживать.
И никто не решается отказаться от старого.
Собеседник:
Обратная совместимость необходима. Без неё невозможно развитие многих корпоративных систем.
Но совместимость должна быть осознанным инженерным решением, а не абсолютным запретом на изменения.
Иногда правильнее выделить стабильные интерфейсы и заменить внутреннюю реализацию. Иногда создать новый слой, постепенно отказаться от прежнего механизма или предложить отдельный путь миграции.
Важно, чтобы развитие архитектуры оставалось самостоятельной задачей.
Если всё внимание уделять добавлению функций, а фундамент не пересматривать, рано или поздно стоимость каждого следующего изменения начнёт расти.
Практик:
И в какой-то момент оказывается, что новая функциональность сама по себе уже не представляет особой сложности.
Сложность заключается в том, чтобы заставить её работать внутри существующей платформы.
Вот тогда и появляется ощущение, что технология больше не помогает.
Ты не создаёшь новое. Ты борешься со старым.
Собеседник:
И, возможно, это самый точный признак того, что пришло время что-то менять.
Не обязательно заменять всю систему. Иногда достаточно отказаться от устаревших механизмов, пересмотреть границы компонентов, открыть нормальные интерфейсы взаимодействия.
Но для этого нужно признать, что архитектура не может оставаться неизменной только потому, что когда-то она была удачной.
Практик:
В конечном счёте технология должна освобождать нас от лишней работы, а не создавать её.
Мы должны тратить время на новые идеи, функции и возможности, а не на борьбу с собственным кодом.
Собеседник:
Наверное, ради этого мы их и создаём. Наверное...