В прошлой статье о low-code в enterprise-решениях я обращался к бизнесу. Однако на «Хабре» бóльшая часть пользователей — инженеры (Кэп!), и в комментариях к статье я увидел резонное количество типичных возражений по LCDP (low-code development platforms). И пока те, кто не знает про Эффект Даннинга — Крююгера, уже ищут кнопку dislike, давайте разберем наиболее частые заблуждения и мысли. На мой взгляд, наиболее частые заблуждения следующие. Кто-то думает, что low-code — это использование готовых продуктов (а не философия разработки) Под low-code понимают развитые code-first платформы. Кто-то из коллег приводил в пример даже WordPress. В low-code отсутствует нормальный DevOps (code review, versioning, deploy, etc.), нормальное переиспользование кода и прочие абстракции. Ну и вообще, low-code это для каких-то типовых решений (для которых предназначен no-code). Разработчикам лучше писать код с готовой ценностью, а не разрабатывать конструкторы. «Low-code можно не понимать, это какой-то артефакт. Мы продолжим кодить как обычно». Впрочем, некоторые разработчики и про DevOps до сих пор не всё понимают и думают, что это должность. Так что с low-code ситуация не уникальна. Почему я решил поднять тему low-code и перспектив развития IT-отрасли? По образованию я физик и предприниматель. В середине 90-х был собственником ISP (интернет-провайдера), после этого был в должностях от инженера в «Билайне» до управляющего партнера компании, специализирующейся на создании ПО по автоматизации (текущая должность, на которой я 7 лет). И сейчас интересно поразмышлять о том, что будет завтра. Уровень абстракции кода растет. Начиная с машинных команд, уходя в процедурное программирование и отказываясь от управления памятью, с повышением количества фреймворков и развитием высокоуровневых языков, что будет завтра? Будет ли уровень абстракции разработки повышаться ещё, и если будет, то каким образом? При этом, потребность в новых продуктах и автоматизации растёт. Дефицит специалистов в отрасли сейчас легко отследить на примере роста окладов: он опережает рост производительности труда в IT-сфере. Кроме того, чем дольше одна команда разработки остаётся на проекте, тем глубже она погружается в операционное сопровождение проекта: большее количество фич порождает большее количество необходимых правок. Расходы на разработку увеличиваются, и одновременно возникает конфликт интересов: бизнесу нужно меняться быстрее, а разработчики хотят интересных задач. Но бóльшая часть изменений у бизнеса — неинтересная. На подобные вызовы IT-отрасль всегда отвечала повышением уровня абстракции и упрощением разработки. «Эпоху ассемблера» сменила «эпоха C++», затем наступила эпоха высокоуровневых языков с полным отсутствием управления памятью и ресурсами — и далее количество фреймворков и библиотек только увеличивалось. Нет никаких предпосылок к изменению этого тренда. Давайте порассуждаем, сможет ли low-code продолжить его. В Рунете каждая статья о low-code заканчивается комментариями о несовершенстве конкретного продукта (продуктов). Отдельно о продуктах поговорим чуть ниже, а для начала предлагаю подумать о концепции low-code в целом. Разработчики поставляют заказчику конечную ценность. Вёрстка элементов, новые поля в сущностях, логика расчёта и потоки интеграции — всё это реализуется через программный код. Да, у него бывают какие-то настройки, которые иногда позволяют вносить изменения без привлечения разработчиков. Но на бо́льшую часть change requests всё-таки отвечают разработчики. У разработчиков тут может возникать два желания. Как бы нам писать только интересный код, а скучные операционные задачи ("кнопку подвинуть") передать кому-нибудь другому? К нам для операционных моментов пусть обращаются лишь в редких кейсах, количество которых в идеале должно уменьшаться и дальше. Если нас и просят об операционных изменениях, пусть делают это более конкретно. На коммуникацию должно уходить меньше времени. И хотелось бы, чтобы разбираться в собственном коде, который, возможно, полгода никто не трогал, было проще. В code-first реализовать эти желания сложно. Представьте, что вы поставляете клиенту не непосредственно конечную ценность, а конструктор для реализации этой ценности. Нет, конечно, первичный функционал в вашем конструкторе придётся реализовать вам для целей отладки. Но при этом вы сможете создавать такие вызовы, функции и компоненты, которые... Являются самодокументируемыми в подавляющем большинстве случаев. В каждом компоненте есть настройки, которые делают его переиспользуемым. Здесь важно отметить, что в code-first платформах тоже много настроек, и они даже разнесены по компонентам. Однако на практике их применение не позволяет снять с разработчика бо́льшую часть операционной работы. Из этого и других компонентов можно собирать принципиально новую ценность для бизнеса. Технически это всё те же интерфейсы, компоненты бизнес-процессов и интеграции, но для бизнеса это принципиально разный функционал. Если требуется какая-то очень эксклюзивная логика (один из компонентов отсутствует) и эта логика явно не будет переиспользуемой, вы сможете вставить нужный компонент, написав небольшой кусочек кода. В отличие от code-first систем, здесь не нужно писать весь модуль или микросервис — вы вставите код в нужный фрагмент без сервисной обвязки («сахара»). Часто такой код легко читается не только разработчиком, но и опытным менеджером или бизнес-аналитиком и состоит из 2–20 строк. Сталкиваясь с новым требованием, вы или собираете новый функционал в уже созданном конструкторе, или дописываете в нём активити и компоненты, если они отсутствуют. Если посмотреть на low-code разработку глазами code-first разработчика, то меняется в первую очередь уровень абстракции компонентов. Кроме привычных сервисов, библиотек, конструкторов, есть ещё один, более высокий уровень абстракции — абстракция бизнес-логики. Это справедливо и при использовании готовых LCDP, и при разработке в парадигме low-code. В дискуссиях я раз за разом сталкиваюсь с тем, что под low-code понимаются просто очень гибкие системы. Например, «Битрикс» — потому что «в нём же есть бизнес-процессы и моделирование таблиц» — или WordPress. LCDP — это такая платформа, в которой всё сделано на базе конструктора, ведь если это не так, рано или поздно поддержание такой платформы перейдёт в code-first. Я бы обозначил следующие критерии LCDP. Ядро системы содержит только элементы конструктора и всё, что к нему относится, т. е. вам не придётся применять code-first подход для реализации того, для чего предназначена LCDP. В графическом редакторе можно вставить код там, где он нужен. А в некоторых платформах можно и слегка переопределить код текущего компонента. Приведу излюбленные нами примеры. ETL / ESB Talend, WSO2 — low-code механизмы для построения интеграций. Mendix, Pega, Appian, OutSystems, Caspio — как платформы для создания приложений разного класса. Reify, Builder.io, Bildr — для фронта. Из новичков 2021 года — Corteza (полностью open-source, Go + Vue.js), Amazon Honeycode. Для игроманов — давно ли вы смотрели на Unity и продукты на его основе? Видели ли Construct? Российские — ELMA BPM, Creatio (разработка «Террасофт») и Comindware, универсальная CUBA Platform, Jmix. Продукты особо крупных вендоров — Microsoft Power Apps, Oracle APEX, Salesforce Platform, IBM BAS, SAP BTP. Частично open-source — Builder.io (фронт), Bonita, Joget. Есть и пограничные случаи. Например, Pimcore, которая в части фронта, workflow, моделирования инфомоделей с калькулируемыми полями является по своей сути low-code (с некоторыми оговорками, но это не тема данной статьи). Если же пытаться делать что-то за рамками этого, вы свалитесь в традиционное поддержание монолита. Или тот же «Битрикс». В нём удобно моделировать данные и строить бизнес-процессы, в которые при желании упаковывается PHP-код в low-code стиле (т. е. без длинных инициализаций). Однако огромный объём коробочного функционала, созданного не в LCDP-стиле, и отсутствие развитых инструментов low-code в других частях приводят к традиционному code-first. Короче, если вы слышите, что «мы пробовали low-code платформу — и у нас ничего не получилось», советую разобраться в деталях. Может быть: это была не LCDP; это была действительно плохая LCDP (такого — сколько угодно); команда пыталась писать в LCDP больше кода, чем нужно. Вместо переиспользуемости — один кастомный компонент, куда вставляется огромная портянка кода, мы встречали такое! Это миф. Вы найдёте эти компоненты в подавляющем большинстве платформ. Многие (Mendix, Pega) имеют собственные CI с элементами low-code. Хотя, безусловно, проводить ревью не всегда просто. Если с кодом компонентов всё понятно — там всё так же, как и в традиционном code-first, — то по поводу того, что можно сделать в конструкторе… Представьте, вы разработали на Unity ходилку-стрелялку, поменяли стены, добавили горы, а потом сохранили и отправили всё это на ревью. Понятно, что версионировать изменение каждой стены вы не станете, и у вас будут огромные версии изменений, разобраться в которых в принципе будет достаточно сложно. Тем более когда дело касается визуальных изменений и вставок кода. Процесс ревью это осложняет в той мере, в какой увеличивается количество изменений за один коммит. С переиспользуемостью тоже обычно всё в порядке: можно использовать процессы в качестве подпроцессов, можно из одной «джобы» вызывать другие и пр. Если есть желание сделать хорошо — с переиспользуемостью проблем не будет. Разработчики обычно брезгливо относятся к самой идее того, что могут что-то накликать мышкой. Между тем подавляющее большинство задач разработчика — не rocket science, а рутина. Та самая, которой заниматься неинтересно и от которой хочется побыстрее избавиться. В рамках проекта вы ограничены в выборе задач. Маловероятно, что к вам будут попадать исключительно интересные и креативные (это подразумевает, что кто-то другой займётся скучными задачами, и тогда всё вышесказанное применимо и к этому бедному человеку). Совсем не заниматься мелкими, а порой и однотипными, скучными вопросами почти невозможно. Просто потому, что кто-то ими должен заниматься. Как ситуация поменяется в рамках LCDP? Скучные задачи никуда не денутся и будут возникать с той же частотой, но, вместо того чтобы тратить на них уйму часов, вы сможете закрывать их в разы быстрее или вообще передавать не разработчику. Зачем писать ещё одну интеграцию между системами, когда вы быстрее сделаете её через ETL-решения? Зачем забивать спринт созданием нового экрана, если это может накликать дизайнер? Чем быстрее вы закрываете скучные задачи, тем больше времени у вас освобождается на более интересные. Более того, вы статистически чаще будете получать интересные задачи, потому что «перерыв» на рутину сократится в разы. А что с реально талантливыми разработчиками, теми, кто любую самую сложную задачу делает изящно и быстро? Сдав задачу в виде кода и получив через полгода change request, они сталкиваются со следующим: надо вспомнить, как тут что написано; надо бы отрефакторить — код быстро устаревает. Но очень редкая команда подписывается под рефакторинг. И редкий бизнес-пользователь поймёт, почему минорную правку ему оценили в несколько дней. Что в итоге? Мы хотели писать интересный код, но через какое-то время ничего интересного не пишем. Нам остаются операционка и угрызения совести за то, что тут всё уже не очень красиво. Если же вы мыслите в плоскости LCDP, дело не ограничивается только более быстрым решением рутинных задач. Рефакторинг происходит не на уровне конечных ценностей, а на более высоком уровне абстракции — на уровне реализации компонента конструктора. Как следствие, вам приходится больше думать и больше проектировать. Меньше областей остаются без вашего надзора, сделать плохо поддерживаемую задачу в LCDP намного сложнее ввиду того, что как минимум плохой нейминг или плохую логику могут обнаружить даже не разработчики. Сам подход заставляет вас больше мыслить абстракциями. Лирическое отступление. Многие тимлиды конкретно для себя решают эту задачу так: реализацией занимаются другие члены команды, а они думают. Ни к чему хорошему это не приводит. Такие тимлиды часто начинают скучать по коду, а команда в целом становится более хрупкой. Антихрупкость таких людей обеспечивается за счёт хрупкости других членов команды, которые выступают в качестве машинисток. Этому пороку могут быть подвержены и традиционные, и low-code разработчики. Можно не думать о будущем разработки, если допустить, что: количество задач для разработчиков будет расти не медленнее, чем количество самих разработчиков и субститутов разработки (с учётом повышающейся производительности труда); бизнес сможет оплачивать растущие аппетиты разработки и не разорится при этом (т. е. ROI в IT всегда будет положительным); другие типы инвестиций не будут конкурировать с инвестициями в IT. Давайте проведём мысленный эксперимент и прикинем, насколько всё это вероятно в реальной жизни. Сейчас дефицит разработчиков в мире — около 10 %. Я не могу предсказать будущее, но могу представить, какие условия нужны, чтобы этот дефицит оставался всегда. Первое: производительность разработчиков не должна повышаться настолько, чтобы она могла компенсировать разницу в дефиците (т. е. на 10 % относительно нынешней производительности). Второе: количество разработчиков не должно расти быстрее, чем количество задач. Дополнительное условие — количество субститутов разработки не должно снижать этот дефицит. А это противоречит фундаментальному закону спроса и предложения, ведь спрос всегда балансируется предложением до равновесного значения. Что мы видим сейчас? Огромное количество людей или думают о переквалификации в IT, или уже находятся в процессе переквалификации. По данным опросов, каждый пятый разработчик не имеет профильного образования и пришёл в IT после окончания курсов. И это не считая повальных курсов программирования даже с детского сада и школы и всё увеличивающегося потока студентов IT-специальностей в вузах. IT начинает отбирать потенциальных специалистов у других специальностей. Этот маховик раскручивается медленно, но верно. В отчётах инвестиционных банков рынок no-code решений (которые являются прямыми субститутами разработки) уже сейчас выглядит примерно так. И если вы посмотрите на этот список, то увидите, что количество продуктов растёт. Наберите в поисковике «название любой компании low-code/no-code» — и вы поймёте, что почти все — от российского «Сбера» до американской Apple — думают о том, как существенно повысить производительность труда в разработке. В конце концов, дисбаланс на рынке труда легко прослеживается на соотношении стоимости управленцев (на которых лежит бóльшая ответственность и на которых завязаны мультипликаторы) и мидлов (на которых ответственности существенно меньше). Разрыв по доходам — в 3–4 раза, и это не случайность. При 20 миллионах разработчиков в мире одна только Индия поставляет на рынок по миллиону разработчиков ежегодно (с ежегодным увеличением этого количества), т. е. существует некоторая вероятность, что в будущем дефицит разработчиков может не сохраниться. Есть и более радикальные суждения: у Германа Грефа, например, или у футуролога Герда Леонгарда. Чем дороже разработка, тем больше разрыв между технологическими компаниями и всеми остальными. Те, остальные, вынуждены встраиваться в экосистемы гигантов. А экосистемы гигантов имеют очень высокую производительность труда (в силу объёмов). Это само по себе заставляет компании уходить в чужие экосистемы. Было время, когда затраты на IT были несущественными. Но программное обеспечение становится всё более сложным и разнообразным, и стоимость ИТ-инфраструктуры является значимым фактором для стартапов и одной из основных статей бюджета. Чем дороже IT, тем больше субститутов для инвестиций. Почему в IT сейчас много денег? Организации видят в цифровизации хорошо окупаемые инвестиции. Волна цифровизации пройдёт (все компании будут в какой-то степени диджитализированы, а прочие уйдут с рынка), нужно будет сопровождать и поддерживать применённые решения. При всё растущей стоимости IT не встанет ли вопрос о поиске иных источников заработка? Не станет ли на каком-то этапе стоимость IT столь значимой, что будет автоматически отсекать бо́льшую часть новых — ныне рентабельных — проектов? Я рекомендую разработчикам посмотреть в сторону low-code и как минимум выполнить несколько задач на любой из таких платформ — для расширения собственных границ. Мы должны понимать область применимости, видеть срез текущих возможностей и изучать что-то новое, ведь на то мы и инженеры, чтобы смотреть на новые технологии глазами практиков. Возможно, вы не найдёте ни одной LCDP, которая решила бы ваши задачи, но как минимум исследовать этот тренд для развития инженерной эрудиции сегодня может быть полезно.