software-development
January 22, 2023

Обратная сторона фреймворков

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

Фреймворк (Framework) — «Frame of work», если дословно: «рамка работ». Большая такая библиотека с окружением и утилитами, вокруг которой вы обязаны выстроить ваш софт по определенным правилам. Эдакий железный х#й столб, на который намотано то что вы считаете «своей разработкой». Ваши любимые Angular, React, Spring, Hibernate — эти самые фреймворки.

Хозяюшке на заметку.

Профит

Зайдем с  козырей:

да, это ускоряет разработку.

Особенно на начальном этапе.

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

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

К сожалению на этом все хорошее заканчивается и начинается наше любимое:

одна сплошная бесконечная жопа.

Все как обычно, вообщем.

Когда выбрал Angular для своего нового проекта.

Проблемы и последствия

Самое первое и очевидное:

фреймворк — большой, сложный и не ваш.

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

И опыта.

Рассказы про «открытый код» и «возможность форка» так рассказами и остаются (по большей части) — некому и некогда таким заниматься на обычном проекте обычной компании.

Просто представьте масштаб работ по созданию форка с последующей поддержкой для какого-нибудь Spring, Angular или Hibernate — «топор рубить устанет».

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

Поэтому:

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

Вырезать из проекта Ангуляр или Реакт — очень и очень сложное занятие.

Детские годы чудесные.

Проблемы развития

Вспомните ваше детство: как вы росли, как изменялось ваше тело — из младенца в ребенка, из ребенка — в подростка, из подростка -в СИЗО во взрослую особь.

Теперь представьте, что в какой-то момент ваш скелет перестал расти.

Вот вам 5, спокойно себе бегаете-прыгаете. Затем вам уже 15, мыщцы, органы — все выросло, а скелет — нет.

Представили?

Вот что-то такое и происходит с программами, основанными на чужих фреймворках, если в какой-то момент развитие фреймворка останавливается.

Думаете что шанс на безвременную кончину какого-то популярного фреймворка ничтожны?

«На ваш век хватит»?

Ознакомтесь с небольшими списками павших:

https://wiki.python.org/moin/WebFrameworks, раздел «1.5. Discontinued/Inactive Frameworks»
https://www.doomworld.com/forum/topic/120735-list-of-web-browser-plugins-that-are-dead-deprecated-discontinued-extinct-with-the-rise-of-html5-https/

Ну и целый отдельный проект-хранилище для мертвых проектов:

https://attic.apache.org/

Вообщем преждевременная смерть в мире ИТ — обыденность.

Но это конечно не единственный вариант, из плохих.

Еще большее зло

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

Вот хороший пример:

в проект JHipster пришел новый крупный спонсор Okta, у которого все продукты про авторизацию и безопасность. С тех пор никаких других вариантов авторизации через соц.сети в проекте нет — только через сервис Okta.

Как-то так выглядит конфликт интересов в бизнесе.

Лучшие мировые практики

Очевидно что проблема с фреймворками не нова и популярные проекты каким-то образом ее решают.

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

Atlassian JIRA

JIRA

Решение:

затащить фреймворк целиком внутрь проекта и дальше развивать и поддерживать своими силами.

Проект, основанный в 2002м году двумя студентами на 10к долларов кредита имел ровно один шанс на успех: взять то что было под рукой из бесплатного и быстро-быстро начать писать код.

Под рукой было вот это:

As Jira is a web application, users interact with Jira using a web browser. Jira uses OpenSymphony's WebWork 1 to process web requests submitted by users. Please note that WebWork 1, not 2, is used. WebWork 1 is a MVC framework similar to Struts. Each request is handled by a WebWork action which usually uses other objects, such as utility and Manager classes to accomplish a task.

https://developer.atlassian.com/server/jira/platform/architecture-overview/

Спустя 21 год, Jira все также использует именно этот фреймворк. Вернее уже его клонированную и улучшенную версию. Да, они полностью затащили фреймворк к себе и теперь сами его поддерживают.

А вы так сможете? Хватит ресурсов?

Jenkins CI

Jenkins

Решение:

cделать свой собственный фреймворк, как часть приложения.

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

https://github.com/jenkinsci/stapler

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

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

Насколько разумно так поступать в реалиях коммерческой разработки — очень большой вопрос.

Но примеры есть.

WildFly Application Server Console

WildFly

Решение:

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

Wildfly (когда-то JBoss) это такой JEE (J2EE в прошлом) сервер приложений, очень популярный.

Делает его (с тех пор как купила) компания Red Hat, когда-то создавшая первый коммерческий Linux для компаний, чем задала на годы вперед правила монетизации решений с открытым исходным кодом.

Очевидно что компания богатая, известная и имеющая серьезный вес в Open Source движении.

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

Поэтому ситуация, когда в ключевом фреймворке что-то поменяется и затронет бизнес Red Hat — просто не может произойти.

Ваш тренер по духовному апгрейду.

Личный опыт

Я хоть и сталкивался на практике со всеми описанными выше вариантами — не могу сказать что они массовые.

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

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

Но поскольку миграция и апгрейд используемых фреймворков дело сложное — собственных компетенций может не хватить. Поэтому разумно позвать специалиста со стороны (например меня да)

Вот примеры задач по миграциям и обновлению что я проводил лично:

  • JQuery -> AngularJS -> Angular2 -> Angular5 -> Angular8 -> Angular ..
  • Java 1.2 -> 1.3 -> 1.4 -> 1.5 -> 1.6 -> 1.7 -> 1.8 -> 9 -> 11 -> 19 -> ..
  • J2EE -> Spring
  • J2EE -> JEE -> Jakarta EE
  • MyBatis -> JPA
  • Swing -> JavaFX
  • Ant -> Maven -> Gradle

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

Во-первых, сам апгрейд возможен всегда.

Ни размер проекта ни степень устаревания не являются препятствием. Чтобы там не рассказывали клоуны в интернете другие разработчики.

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

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

Символ распада и деградации.

С переписыванием с нуля вообще все куда сложнее и рисковее: можно сломать «ощущение от использования» — набор паттернов использования, к которым пользователи уже привыкли.

Причем сломать можно чем угодно:

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

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

Не верите? Вспомните Skype — самый яркий пример.

Мой проект

Paster, трижды переписанный и многократно обновленный.

Помимо коммерческой разработки, у меня есть личный проект с непростой историей:

https://github.com/alex0x08/paster

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

Apache Tiles - заморожен в 2017м, не поддерживает Java старше 1.8

MooTools - развитие остановилось в 2016м, проблемы с работой в новых браузерах.

Compass Search - активная разработка закончилась в 2010м. Проект заморожен в угоду Elasticsearch, который хоть и активно развивается но слишком большой для встраивания и локального использования.

Некромантия

Чтобы оживить проект «Paster» и продолжить историю, пришлось проводить глобальную модернизацию:

Apache Tiles — был сделан форк, вычищен анализатором кода от устаревших частей, все ненужное — отрезано, нужное — модернизировано для поддержки последних версий Jakarta EE.

MooTools — был убран полностью, часть плагинов была переписана вручную на ES6, остальное — удалено.

Compass Search — заменен на Hibernate Search, с фактически полным переписыванием логики поиска.

Помимо этого было неоднократное обновление Spring: 3.x -> 4.x -> 5.x -> 6.x , Hibernate, библиотек Apache, Bootstrap и еще кучи всего.

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

Горькая правда на английском

Выводы

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

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

Фреймворки дают свой эффект на начальном этапе, но уже существующий большой проект они никак не спасут.

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

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

Главное не забывать о последствиях.