Спойлер - никак.
Очень часто программисты приходят уже на существующий проект и сталкиваются с некоторым количеством неоправданных вызовов. Но так бывает не всегда. Единицам везёт прийти на новый проект и начать всё с чистого листа. И в этот момент мы, нередко, наблюдаем эту чудесную метаморфозу: как, спустя два года, карета превращается в тыкву. Расскажу немного об этом.
Как это часто бывает
Представьте себе, что вас позвали на новый проект как эксперта и вообще микроархитектора своей части приложения. Довольно почётная и интересная работа. Вы в праве выбирать любые технологии, опираясь на своё видение прекрасного.
Фокус заключается в том, что в 9 случаях из 10 выбор будет сделан либо в сторону "чего-то новенького и перспективненького", но это больше относится к относительно молодым разработчикам, либо в сторону "того, что знаю": те, кто наигрался в технологии уже не хотят осваивать очередной фреймворк с преферансом и куртизанками.
Казалось бы, наиболее здравым был бы подход изучить технические требования к будущему программному продукту, выбрать технологию, которая максимально соответствовала бы задаче - и вуаля...
Только это всё почти никогда так не работает: полный набор технических требований, нередко, есть только в голове у архитектора, а то и вовсе отсутствует. А наиболее соответствующий технологический стек - это тот самый сферический конь в вакууме: он вроде есть, но никто его не видел. Поэтому чаще всего выбирается какой-то, а потом начинается борьба с нюансами.
Невидимые перспективы
Как говорил герой одного известного фильма: "знал бы прикуп, жил бы в Сочи". При разработке программного обеспечения, изначально, очень многое неясно. То есть да, есть понимание масштаба задачи, какие-то требования (какие-то, но всегда недостаточно полные), в соответствии с которыми приходится решать задачу.
Иными словами, когда проект начинается, можно предполагать, что будет в нём дальше, что-то можно даже угадать или предсказать. Но всё равно, в какой-то момент проект выйдет за рамки спроектированного. И тогда либо переделывать что есть, либо ставить костыли. Бизнес любит костыли (так как это дешевле), программисты - нет (потому что поддерживать такой код становится сложно).
Расскажу про свой опыт. Участвовал я как-то на проекте, где мы писали довольно большую систему. Как архитектор фронтенда, я выбрал популярный на тот момент angular 1, который очень хорошо соответствовал широкому кругу ожидаемых задач.
Но, как обычно, всё пошло не так, как ожидалось.
Во-первых, когда значительная часть функциональности была реализована, выяснилось, что количество одновременно отображаемых и обслуживаемых элементов на экране может быть больше, чем фреймворк может эффективно обрабатывать - начались тормоза, что привело к лютой оптимизации процессов и ряду непопулярных решений (костылей, проще говоря).
Во-вторых, масштаб будущего приложения оказался сильно больше заявленного: новая версия потребовала большой переработки отдельных компонентов и поиска дополнительных средств оптимизации производительности, что явилось следствием недозаявленной функциональности.
В-третьих, полная неопределённость на проекте. То есть надо было работать с моделями данных, которых ещё нет. То есть их не было даже на черновиках, так как разработка фронтенда опережала как разработку бэкенда, так и работу архитектора.
Это был интересный опыт, который многому учит. Главным образом тому, что повторно проходить через него уже не хочется. А при выборе технологий и фреймворков лучше к ним не сильно привязываться (хотя это не всегда возможно), потому что вероятность смены лошадей на переправе может очень даже потребоваться.
Если интересно, то вышли мы из этой истории довольно изящно: интегрировали возможность взаимодействия с react-ом и начали постепенно переходить на более производительный фреймворк.
Так как выбирать технологию
Вспоминается старый анекдот про первую брачную ночь в ночной сорочке или без ней. Что ни выберешь, всё равно, в какой-то момент появятся задачи, которые превзойдут возможности выбранного фреймворка/технологии/языка.
Если бы меня спросили совет про разработку нового приложения, то я ответил бы ровно то, что в своё время рекомендовал мне мой наставник: слабая связанность, сильное зацепление (с годами простые истины обретают смысл).
Проще говоря, решая задачу лучше выбирать решение, которое будет относительно легко отделить и убрать или заменить. И касается это не только способа написания кода, но и вообще подхода к разработке и проектированию.
Модули, скорость и очерёдность загрузки, тесты, работа с сетью, графика и прочее - всё это должно быть условно-автономным, отделяемым и расширяемым. При этом, самым сложным будет не реализовать идею, а выдержать баланс связанности.
Избыточность и недостаточность
Есть ещё одна тема, которую пропустить нельзя и касается она средств разработки. Приведу на примере фроненда, но, уверен, схожая проблематика есть везде.
Итак, разработка во фротенде, нынче, содержит 3 возможности создания приложения:
- javascript он же ecmascript, который необходимо прогонять для транспилятор, чтобы он поддерживался старыми браузерами (и необязательно этого делать для современных, хотя и не для всех).
- typescript - обёртка для javascript, добавляющая типизацию: компилируется в javascript и проходит транспиляцию, однако на этапе компиляции анализируется на потенциальные ошибки при использовании интерфейсов. В силу типизации часто требует импорта типов интерфейсов для повторного использования.
- webassembly - компиляция таких rust или c++ (возможно и других языков высокого уровня, но я, пока что, не сталкивался с такими) в инструкции вроде ассемблерных (они похожи, но немного отличаются) для условной виртуальной машины браузера.
Так вот, все три подхода имеют свои преимущества и недостатки.
Webassembly позволяет упаковать уже рабочее приложение либо использовать решения очень глубокой обфускации, очень сильно затрудняющих реверс-инжиринг исходного кода. Хорошо подходит для обработки особо чувствительных данных и "упрятывания" от посторонних глаз некоторых данных и функциональности.
Typescript позволяет сократить ошибки на обращение с данными ещё на этапе написания кода. Отлично подходит для обработки относительно плоских и стабильных проектов без частого обновления структур данных с редким и, желательно, не перекрёстным использованием интерфейсов. Но при высокой динамике разработки и переиспользовании кода (например компонеты или цепочки компонентов) - порождает настоящую головную боль из-за огромного количества зависимостей, распределённых и переповторённых, зачастую, по всему проекту и требующих неоправданно больших трудозатрат для решения частых динамичных задач.
Javascript прекрасно подходит для решения задач, где цена ошибки не велика, а динамика изменений высока. Обратной стороной является потенциальная уязвимость для ошибок типа и приведений данных. Сравнение двух пустых массивов на равенство и неравенство, например, может происходить в разных браузерах по-разному, а сравниваться при разных видах сравнения могут разные параметры (например, в одном случае длина, во втором - строковое значение).
По логике вещей, в любом веб-проекте, webassembly должен занимать от 0 до 5% кодовой базы (скорее 0, потому что поддержка технологии всё ещё оставляет желать лучшего), typescript - до 10% и работать с моделями данных, гарантируя их целостность и, может быть, с некоторыми библиотеками, работа с которыми имеет определённую чувствительность. Прочее - лучше оставлять на откуп javascript: постоянные изменения интерфейса, переделки, дополнения и исправления, чаще всего, не требуют пристального наблюдения, а цена ошибки - невелика.
К сожалению, по такому пути редко кто идёт, предпочитая выбирать одну технологию и тиражировать её на весь проект (я привёл пример с языками разработки, но это также актуально и для всего остального). Популярный нынче typescript со встроенной защитой от начинающего программиста создаёт довольно большую избыточность и сложность даже в местах, которые и без типизации отлично себя чувствуют.
Вместо выводов
Как ни крути, технологии тоже имеют свой цикл популярности. Помните jQuery? Или, возможно, вы её не застали. А, между тем, существуют проекты, на которых она не просто используется, но и вполне уверенно себя чувствует. И, главное, необходимости отказываться от неё - нет.
Технология - это просто один из множества подходов и, как правило, всё новое - это переработанное старое с хорошим маркетингом. Тот же самый typescript, несмотря на медийную поддержку, щедро оплаченную из кармана Microsoft (мелкомягкие тоже хотят себе кусок web-рынка), всё же, популярность его претерпевает изменения: согласно GitHub она растёт, а вот согласно предложениям о работе - падает (даже если вы знаете typescript - знание javascript всё равно требуется).
Главное, не забывать, что выбор любой, даже самой совершенной и актуальной на текущий момент технологии, не гарантирует того, что в процессе работы она не продемонстрирует непреодолимые ограничения и не потребует серьёзного пересмотра подхода.