В этом посте я расскажу о тех проблемах с которыми в течении года сталкивалась наша Scrum Front End команда при работе над приличным проектом. Мы начинали разрабатывать проект с нуля используя стек технологий React + Typescript. Оглядываясь назад я вижу многие миллионы выброшенные впустую просто из-за того, что процесс разработки не был поставлен с самого начала правильно. Но на это есть свои причины.
Сначала нужно было выиграть тендер. Для этого нужно было быстро запилить Minimal Valuable Product. И здесь кроется первая ошибка обошедшаяся в приличную сумму для нашего заказчика. Она звучит так: быстро запилить MVP. Заказчик хочет быстро увидеть результат, но это означает что мы жертвуем хорошей инфраструктурой, надежной архитектурой и через год мы пришли к тому что наша Front End архитектура требует серьезного рефакторинга. Порядка нескольких месяцев. Так мы слили 500 000 рублей.
Оглядываясь назад я с уверенностью могу сказать, что первым делом нужно было взять в рассчет весь функционал который заказчик хотел увидеть в конечном итоге через несколько лет. Так мы смогли бы избежать архитектурных ошибок в стиле «данная архитектура этого не предусматривает». В результате каждая крупная фишка требовала серьезного рефакторинга.
Для того чтобы выиграть тендер наша компания послала разработчиков не имевших опыт в проектировании крупных приложений и надежных расширяемых систем. Понятное дело, тендер не заказ, и разбрасываться хорошими кадрами никто не хочет. Но отсутствие технического архитектора на (уровне классов) привела к тому что наше приложение превратилось в спагетти код и перестало удовлетворять требованиям SOLID. И здесь кроется ошибка каждого заказчика. Невозможно поддерживать постоянный темп разработки без увеличения ресурсов команды. Принцип Agile «Инвесторы, разработчики и пользователи должны иметь возможность поддерживать постоянный ритм бесконечно» работает только вслучае, если с самого начала были известны и проработаны требования, весь набор функционала, спроектирована надежная и расширяемая архитектура (одним словом, если каждый класс продумывался с учетом конечной функциональности системы) и четко поставлены процессы. И это надо было делать в MPV прежде чем пилить продукт. В противном случае, с течением линейного времени сложность приложения растет экспоненциально. Это значит запилить фичу через год будет стоить на O(e(N)) дороже чем в начале.
В нашей команде единственный дизайнер был удаленным сотрудником. Это была серьезная ошибка. Удаленный сотрудник всегда живет своей жизнью. Он рисует себе дизайн, красиво и ладно, заказчик счастлив. Но все эти прелести в конечном итоге сводятся к тому что на одни и те же логические формы у нас присутствует N разных стилей и версток. С самого начала стоило поставить требование: стилизируй определенный фреймфорк (у нас был Ant Design). Если там чего-то нет, делай из того что там есть. Заказчик думал что React это конструктор из кубиков. И он до сих пор не понимает по чему мы по 4 дня пилим примитивные формы. React это конструктор, но только в том случае если у нас в самом начале разработки есть набор однотипных переиспользуемых компонентов (UI фреймворк). Дизайнер без опыта верстки этого никогда не сделает сам. Разработчик никогда об этом не скажет заказчику. За этим должен следить лидер. А значит лидер у Front End команды должен быть Front End разработчком в прошлом, а не Back End как это бывает всегда. Следовательно мы приходим к тому что полнофункциональная команда Agile должна содержать компетентного лидера по каджому из направлений ее работы (FE, BE). Эти лидеры должны обладать сильными Soft скиллами чтобы донести до заказчика то, что я пытаюсь описать в этой статье. А это очень и очень не просто.
Когда мы вышли в первый релиз мы поняли что у нас постоянно что-то ломается в самый последный день перед демо. На протяжении всего года разработки каждая релизная ветка превращается в адский набор костылей (отключи это, убери то) которые потом магическим образом оказываюся в develop ветке. И идет серия коммитов (включи то, включи это). Через год мы пришли к выводу что нам нужно иметь четкую политику ветвлений. Но самое главное, ответственного человека который бы устранил существующий хаос. Это означало: либо умерить хаотичекие желания заказчика, либо умерить хаотические баги, либо на каждом стенде иметь свою конфигурацию отключающие какие-то графические фичи или кнопки. Оборачивать каждую кнопку в if оператор это безумие. Мы пришли к тому что нам нужна фиче-модульная Front End архитектура на базе плагинов (отключи — включи). Я долго думал как достичь подобной архитектуры. Но одно я понял точно. Нам был нужен полноценный контекст. Так зародилась библиотека js-beans (https://www.npmjs.com/package/js-beans). Каждый стенд имел свой json контекст. Плагины собирались в цепочку (чейнились) через паттерн Proxy. Так например, у нас был источник данных как отдельный бин, а различные преобразования делались как опциональные Proxy бины замещающие этот бин, но инжектящие его в себя. Например, если нужно произвести масштабирование модели данных для тестирования FPS производительноси, я просто добавляю в json файл строчку включения плагина масштабирования. Сломалось что-то на продакшне, а локально не воспроизводится, влючаю логгер одной строчкой без пересборки стенда (стенд собирается около 20 минут, да и десятка стендов на всех не всегда хватает). Или если нужно быстро выключить какой-то модуль из-за того что его можно сломать (отключаем опциональный бин в контексте).
Шло время, у нас на неделю отключили стенды. Локально разрабатывать фронт было нельзя. У нас небыло предусмотрено автономной архитектуры на моках. Пришлось через боль со скрипом ее запилить. Сейчас, оглядываясь назад, я бы сделал это в самом начале. Но у нас был MVP, и мы были вынуждены писать код без глубокого проектирования. Но заказчик считал нас профессионалами, и думал что мы должны сразу писать код без ошибок. Здесь следующая ошибка. Имя компании не говорит о профессионализме команды. Профессионализм команды определяется профессионализмом лидера команды. Если технического лидера в команде нет, через год ваш проект зайдет в тупик. Так вы сольете еще парочку миллионов.
У нас был удаленный архитектор. Но о нем было известно только одно: он есть. Последняя стадия развития руководителя по мнению Владимира Тарасова. В этом наш архитектор достиг совершенства. Ошибка номер N: у вас нет технического архитектора, который проектирует систему на уровне классов. У вас нет человека у которого можно попросить помощи если ты пришел в тупик. Обращайтесь за помощью в другие более опытные команды — говорил нам заказчик. Но почему-то в других командах никогда не было времени чтобы нам помочь. Наш ПР висит уже второй месяц. Я искренне надеюсь что найдется храбрый человек который его аппрувнет. В результате жизнь наградила наш код богатым изобилием паранормальных явлений в виде магии и наборов костылей на все случае жизни. Недостовало только одного. Специальных аннотаций Magic и @Kostyle. Хорошая идея для следующего ES.
Мы решили что больше мидлов и меньше синьоров выгоднее для проекта. Сейчас мы думаем иначе. Если у вас маленький бюджет, вам необходимо нанимать самых дорогих специалистов. Если у вас, как у нас, с бюджетом проблем нет, можете смело экономить на специалистах и превратить Code Review в битву экстрасенсов.
Мы думали что мы уложимся в квартальные сроки. Сейчас мы думаем иначе. Короче говоря, по хорошему нам нужно переписать проект. И желательно с нуля. Я надеюсь наш заказчик об этом никогда не узнает. Ведь мы только недавно провели шикарный тимбилдинг)
Мы решили поиграться с новыми технологиями, в которых у нас было мало экспертизы. Нам их порекомендовали. Конечно нам хотелось набраться опыта. Сейчас я думаю, что лучше бы использовал только те технологии, в которых у меня есть опыт.
Мы давали оценки исходя из 8 часового рабочего дня. В реальности, оценки стоит давать исходя из 4х часового рабочего дня. Почему никто не включает чай, рассказ интересных историй, поиск туалета по навигатору, разговор по телефону, переписку, изучение новых технологий и самое главное, увлеченных споров внутри команды. Последнее, наверное, самое неизбежное, и самое накладное. Хотя, если честно, за Open Space нужно еще накидывать пару часов. Постоянные разговоры жутко снижают концентрацию. Блажен заказчик, который все это понимает!
Наши эстимации проходили изнурительно и переходили в нудную техническую полемику как ни крути. Эффективность митингов была минимальной. Но мы нашли решение: вкусная пицца. Когда аппетитный запах раздражает нос человек начинает четче выражать свои мысли.
В начале у нас была одна маленькая команда, потом одна большая команда. Планинг занимал часа 2-3. Стендап 30 минут. За что я уважаю нашего PO, так это за то что он решил разделить ее на много мелких и выделить в каждой из них своего мини PO. Наверное, это было лучшим решением за всю историю нашего проекта.
С самого начала у нас не было времени чтобы писать тесты. Через пол года мы пришли к тому что их все-таки нужно было писать. Но времени на это по прежнему мы не находим. Слишком много более приоритетного технического долга накопилось. Не копить технический долг — это утопия. Он всегда будет.
Мои личные субьективные выводы:
Вы вряд ли избежите всех этих проблем даже после прочтения этой статьи. Моя цель показать вам, что это неизбежно. И как бы вы не старались, у вас никогда не будет идеальных условий. Поэтому просто будьте к этому готовы. И перед увольнением, можете смело показать эту статью вашему заказчику. Пусть и он будет морально к этому готов.
P.S.: Максим, если ты когда-нибудь прочтешь эту статью, знай, все что я описал полностью вымышленно и не имеет никакого сходства с нашим проектом) Но все это не важно, ведь сегодня я ухожу в отпуск. Первый отпуск за год кропотливой ненормированной работы! (в качестве FE лида).
Сначала нужно было выиграть тендер. Для этого нужно было быстро запилить Minimal Valuable Product. И здесь кроется первая ошибка обошедшаяся в приличную сумму для нашего заказчика. Она звучит так: быстро запилить MVP. Заказчик хочет быстро увидеть результат, но это означает что мы жертвуем хорошей инфраструктурой, надежной архитектурой и через год мы пришли к тому что наша Front End архитектура требует серьезного рефакторинга. Порядка нескольких месяцев. Так мы слили 500 000 рублей.
Оглядываясь назад я с уверенностью могу сказать, что первым делом нужно было взять в рассчет весь функционал который заказчик хотел увидеть в конечном итоге через несколько лет. Так мы смогли бы избежать архитектурных ошибок в стиле «данная архитектура этого не предусматривает». В результате каждая крупная фишка требовала серьезного рефакторинга.
Для того чтобы выиграть тендер наша компания послала разработчиков не имевших опыт в проектировании крупных приложений и надежных расширяемых систем. Понятное дело, тендер не заказ, и разбрасываться хорошими кадрами никто не хочет. Но отсутствие технического архитектора на (уровне классов) привела к тому что наше приложение превратилось в спагетти код и перестало удовлетворять требованиям SOLID. И здесь кроется ошибка каждого заказчика. Невозможно поддерживать постоянный темп разработки без увеличения ресурсов команды. Принцип Agile «Инвесторы, разработчики и пользователи должны иметь возможность поддерживать постоянный ритм бесконечно» работает только вслучае, если с самого начала были известны и проработаны требования, весь набор функционала, спроектирована надежная и расширяемая архитектура (одним словом, если каждый класс продумывался с учетом конечной функциональности системы) и четко поставлены процессы. И это надо было делать в MPV прежде чем пилить продукт. В противном случае, с течением линейного времени сложность приложения растет экспоненциально. Это значит запилить фичу через год будет стоить на O(e(N)) дороже чем в начале.
В нашей команде единственный дизайнер был удаленным сотрудником. Это была серьезная ошибка. Удаленный сотрудник всегда живет своей жизнью. Он рисует себе дизайн, красиво и ладно, заказчик счастлив. Но все эти прелести в конечном итоге сводятся к тому что на одни и те же логические формы у нас присутствует N разных стилей и версток. С самого начала стоило поставить требование: стилизируй определенный фреймфорк (у нас был Ant Design). Если там чего-то нет, делай из того что там есть. Заказчик думал что React это конструктор из кубиков. И он до сих пор не понимает по чему мы по 4 дня пилим примитивные формы. React это конструктор, но только в том случае если у нас в самом начале разработки есть набор однотипных переиспользуемых компонентов (UI фреймворк). Дизайнер без опыта верстки этого никогда не сделает сам. Разработчик никогда об этом не скажет заказчику. За этим должен следить лидер. А значит лидер у Front End команды должен быть Front End разработчком в прошлом, а не Back End как это бывает всегда. Следовательно мы приходим к тому что полнофункциональная команда Agile должна содержать компетентного лидера по каджому из направлений ее работы (FE, BE). Эти лидеры должны обладать сильными Soft скиллами чтобы донести до заказчика то, что я пытаюсь описать в этой статье. А это очень и очень не просто.
Когда мы вышли в первый релиз мы поняли что у нас постоянно что-то ломается в самый последный день перед демо. На протяжении всего года разработки каждая релизная ветка превращается в адский набор костылей (отключи это, убери то) которые потом магическим образом оказываюся в develop ветке. И идет серия коммитов (включи то, включи это). Через год мы пришли к выводу что нам нужно иметь четкую политику ветвлений. Но самое главное, ответственного человека который бы устранил существующий хаос. Это означало: либо умерить хаотичекие желания заказчика, либо умерить хаотические баги, либо на каждом стенде иметь свою конфигурацию отключающие какие-то графические фичи или кнопки. Оборачивать каждую кнопку в if оператор это безумие. Мы пришли к тому что нам нужна фиче-модульная Front End архитектура на базе плагинов (отключи — включи). Я долго думал как достичь подобной архитектуры. Но одно я понял точно. Нам был нужен полноценный контекст. Так зародилась библиотека js-beans (https://www.npmjs.com/package/js-beans). Каждый стенд имел свой json контекст. Плагины собирались в цепочку (чейнились) через паттерн Proxy. Так например, у нас был источник данных как отдельный бин, а различные преобразования делались как опциональные Proxy бины замещающие этот бин, но инжектящие его в себя. Например, если нужно произвести масштабирование модели данных для тестирования FPS производительноси, я просто добавляю в json файл строчку включения плагина масштабирования. Сломалось что-то на продакшне, а локально не воспроизводится, влючаю логгер одной строчкой без пересборки стенда (стенд собирается около 20 минут, да и десятка стендов на всех не всегда хватает). Или если нужно быстро выключить какой-то модуль из-за того что его можно сломать (отключаем опциональный бин в контексте).
Шло время, у нас на неделю отключили стенды. Локально разрабатывать фронт было нельзя. У нас небыло предусмотрено автономной архитектуры на моках. Пришлось через боль со скрипом ее запилить. Сейчас, оглядываясь назад, я бы сделал это в самом начале. Но у нас был MVP, и мы были вынуждены писать код без глубокого проектирования. Но заказчик считал нас профессионалами, и думал что мы должны сразу писать код без ошибок. Здесь следующая ошибка. Имя компании не говорит о профессионализме команды. Профессионализм команды определяется профессионализмом лидера команды. Если технического лидера в команде нет, через год ваш проект зайдет в тупик. Так вы сольете еще парочку миллионов.
У нас был удаленный архитектор. Но о нем было известно только одно: он есть. Последняя стадия развития руководителя по мнению Владимира Тарасова. В этом наш архитектор достиг совершенства. Ошибка номер N: у вас нет технического архитектора, который проектирует систему на уровне классов. У вас нет человека у которого можно попросить помощи если ты пришел в тупик. Обращайтесь за помощью в другие более опытные команды — говорил нам заказчик. Но почему-то в других командах никогда не было времени чтобы нам помочь. Наш ПР висит уже второй месяц. Я искренне надеюсь что найдется храбрый человек который его аппрувнет. В результате жизнь наградила наш код богатым изобилием паранормальных явлений в виде магии и наборов костылей на все случае жизни. Недостовало только одного. Специальных аннотаций Magic и @Kostyle. Хорошая идея для следующего ES.
Мы решили что больше мидлов и меньше синьоров выгоднее для проекта. Сейчас мы думаем иначе. Если у вас маленький бюджет, вам необходимо нанимать самых дорогих специалистов. Если у вас, как у нас, с бюджетом проблем нет, можете смело экономить на специалистах и превратить Code Review в битву экстрасенсов.
Мы думали что мы уложимся в квартальные сроки. Сейчас мы думаем иначе. Короче говоря, по хорошему нам нужно переписать проект. И желательно с нуля. Я надеюсь наш заказчик об этом никогда не узнает. Ведь мы только недавно провели шикарный тимбилдинг)
Мы решили поиграться с новыми технологиями, в которых у нас было мало экспертизы. Нам их порекомендовали. Конечно нам хотелось набраться опыта. Сейчас я думаю, что лучше бы использовал только те технологии, в которых у меня есть опыт.
Мы давали оценки исходя из 8 часового рабочего дня. В реальности, оценки стоит давать исходя из 4х часового рабочего дня. Почему никто не включает чай, рассказ интересных историй, поиск туалета по навигатору, разговор по телефону, переписку, изучение новых технологий и самое главное, увлеченных споров внутри команды. Последнее, наверное, самое неизбежное, и самое накладное. Хотя, если честно, за Open Space нужно еще накидывать пару часов. Постоянные разговоры жутко снижают концентрацию. Блажен заказчик, который все это понимает!
Наши эстимации проходили изнурительно и переходили в нудную техническую полемику как ни крути. Эффективность митингов была минимальной. Но мы нашли решение: вкусная пицца. Когда аппетитный запах раздражает нос человек начинает четче выражать свои мысли.
В начале у нас была одна маленькая команда, потом одна большая команда. Планинг занимал часа 2-3. Стендап 30 минут. За что я уважаю нашего PO, так это за то что он решил разделить ее на много мелких и выделить в каждой из них своего мини PO. Наверное, это было лучшим решением за всю историю нашего проекта.
С самого начала у нас не было времени чтобы писать тесты. Через пол года мы пришли к тому что их все-таки нужно было писать. Но времени на это по прежнему мы не находим. Слишком много более приоритетного технического долга накопилось. Не копить технический долг — это утопия. Он всегда будет.
Мои личные субьективные выводы:
- Если ваши разработчики не понимают для чего нужен IoC на FrontEnd, то скорее всего когда они поймут, будет уже поздно.
- Если ваши разработчики непонимают зачем на FrontEnd нужно знание ООП, то ваш код вряд ли можно будет поддерживать.
- Меньше дорогих специалистов лучше чем больше более выгодных.
- Если у вас есть архитектор, скорее всего вам нужен еще один.
- Если вы пилите MVP, допилите его и смените проект.
- Если до вас уже запилили MVP, не ходите на этот проект.
- Если вы запилили MVP и не хотите уходить, скорее всего вы измените свое мнение.
- Если вы запилили MVP и хотите чтобы ваш проект выжил, перепишите его с нуля.
- Если вы покажете эту статью заказчику, скорее всего вас уволят.
- Если вы работаете по Agile, скорее всего вы меня понимаете.
Вы вряд ли избежите всех этих проблем даже после прочтения этой статьи. Моя цель показать вам, что это неизбежно. И как бы вы не старались, у вас никогда не будет идеальных условий. Поэтому просто будьте к этому готовы. И перед увольнением, можете смело показать эту статью вашему заказчику. Пусть и он будет морально к этому готов.
P.S.: Максим, если ты когда-нибудь прочтешь эту статью, знай, все что я описал полностью вымышленно и не имеет никакого сходства с нашим проектом) Но все это не важно, ведь сегодня я ухожу в отпуск. Первый отпуск за год кропотливой ненормированной работы! (в качестве FE лида).