«“Сделать приложение для людей” — это не набросать на коленке»: о мобильной разработке в ЦФТ +15




Какие проблемы возникают при увеличении мобильной команды в 10 раз? По каким причинам в одной и той же компании Android-разработчики предпочитают использовать известные библиотеки, а в iOS чаще пишут собственные решения? Каково живётся мобильным разработчикам в финтехе?

В нашей конференции Mobius приняла участие компания «Центр Финансовых Технологий», и в связи с этим мы расспросили двух сотрудников ЦФТ: за iOS отвечал Кирилл Зуев, а за Android — Михаил Емельянов.

Текст получился таким развёрнутым, что мы даже составили оглавление, чтобы легко было перейти к конкретной части:


О компании


JUG.ru Group: Вступительный вопрос: расскажите о компании и о том, чем лично вы занимаетесь в ней.

Кирилл: Коротко рассказать не получится, так как бизнес-направления ЦФТ очень диверсифицированы. Но попробуем «крупными штрихами» про самые популярные продукты и сервисы.

ЦФТ уже третье десятилетие работает на российском рынке финтеха, и мы говорим, что делали финтех, когда ещё такого понятия не существовало.

Сегодня ЦФТ – это и процессинг, и производство софта для большого числа различных финансовых организаций, страховых компаний, государственных корпораций, ритейла.

Это экосистема «Золотая Корона», включающая пул сервисов как b2c, так и b2b-формата: онлайн-обмен валюты, денежные переводы наличными и онлайн, погашение кредитов, программы лояльности, транспортные и социальные карты.

Процессинговый центр «КартСтандарт»: эмиссия и эквайринг карт платёжных систем Mastercard, Visa и «Мир».

Федеральная Система «Город» агрегирует несколько десятков тысяч различных услуг: от оплаты детских садов и коммунальных услуг до внесения налоговых платежей и пополнения транспортных карт.

Сервисы онлайн-банкинга Faktura.ru используют более 130 банков. Автоматизированными банковскими системами ЦФТ пользуются ещё больше различных организаций.

В ЦФТ работают большие подразделения R&D, ML и AI, которые интегрируются практически во все направления деятельности компании. У нас мощная команда информационной безопасности. В общем, это более 3000 человек, которые заняты решением задач финтеха на протяжении уже 26 лет.

Один из «молодых» продуктов ЦФТ основан на сервисе «Золотая Корона – Денежные переводы» (которому уже 16 лет) — это «Денежные переводы онлайн», направление, которое мы запустили в 2016 году. И сегодня это локомотив мобильной разработки в ЦФТ: суммарно в iOS и Android над ним работает 70 человек. И это число продолжает расти, мы планируем к концу года вырасти до сотни.

Также мобильные направления есть в подразделениях «Предоплаченные карты» (развивают решения для карт «Кукуруза», «Билайн», «Kari» и др.), в Faktura.ru, Системе «Город».

А мы с Мишей как раз-таки в подразделении «Денежные переводы онлайн» занимаемся развитием команды, расширением, введением в процессы разработки. Изначально мы работали в дирекции «Предоплаченные карты», команды были небольшие, платформенные, и мы жили в тех концепциях, которые были в 2014-2015 годах.

Михаил: Когда все рядом в одном кабинете сидят, работают, общаются.

Кирилл: Такие небольшие тёплые и ламповые команды, на 10-15 человек с учётом всего — и тестирования, и бэкенда. А теперь у нас новые челленджи.

Михаил: Да, организовать работу 10 разработчиков — это одно, а 50 — совершенно другое. Сюда входят все процессы и по разработке, и по масштабированию команды, и по её профессиональному развитию, да и по самому проекту: если инженеры у нас решают технические задачи, то мы занимаемся развитием архитектуры проекта. Выискиваем проблемы, которые будут мешать масштабированию этого проекта, и пытаемся всячески их решать.

JUG.ru Group: К вопросам роста мы ещё вернёмся, а пока расскажите вот что: чем мобильная разработка в ЦФТ отличается от других компаний, а в чём схожа? Что надо знать о ней тем, кто никогда не работал в финтехе? Требуются ли у вас уже на этапе собеседования какие-то специальные знания?

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

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

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

Конечно, нужны минимальные знания на первичном уровне: как выглядит банковская карта, что такое банковский счёт. Но если есть более глубокие знания, то это позволяет проще и быстрее понимать пожелания аналитиков. Есть разработчики, которые хотят понимать не только «как сделать задачу», но и «для чего».

Есть и своя специфика, например, требования регулятора в лице Центробанка. Но, как правило, это всё учтено в бизнес-требованиях и достаточно их прочитать, задать нужные вопросы, и всё будет понятно.

Есть определённые моменты с точки зрения информационной безопасности, это понятно: финтех – про безопасность. Но не могу сказать, что мобильные разработчики — это первая линия защиты. Всё-таки финтех-продукты проектируются таким образом, чтобы быть безопасными на стороне бэкенда и хранилищ данных.

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

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



Мы их не совершаем, потому что есть code review и есть рекомендации от безопасников, которые сделали нам прекрасный чек-лист В нем прописано, где какая уязвимость должна быть проработана и кем (на стороне бизнес-аналитики, бэкенд-разработчика, мобильного разработчика или тестировщика). Все эти зоны ответственности нам известны, мы просто следуем правилам.

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

Наши iOS-«банки» в 2018-м заняли 4 и 5 места в рейтинге Markswebb в категории Daily banking.

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

Михаил: Я кратко добавлю, что мы и правда ориентированы на клиентов — живых людей, которые по улицам ходят. Раз мы проводим операции с деньгами, мы стремимся сделать их максимально юзабельными, проще и для людей.

При этом, когда сотрудники приходят к нам, они должны понимать, что по-настоящему «сделать для людей» — это не набросать на коленке «как я вижу». До работы в ЦФТ почти весь дизайн и UX я делал сам без дизайнера. Но в компании у нас так не работает. Здесь есть целая UX-лаборатория с дизайнерами, которые проводят эксперименты, и есть фокус-группы, на которых проверяют гипотезы.

И когда к нам приходит человек, он должен понимать, что всё будет ориентировано на то, чтобы клиенту было проще пользоваться продуктом, чтобы не умереть при заполнении формы из 50 полей. Работа идёт именно с ориентацией на потребности конечного пользователя.

Второе — требования к качеству кода. У нас действительно высокие требования к качеству, к ревью, к чистоте архитектуры, применению принципов SOLID на всех слоях. У нас недопустимо ради сроков жертвовать качеством.

И это соседствует с современными технологиями, нет отставания от индустрии. Все Android-продукты сейчас пишем на Kotlin, а iOS на Swift. В Android используем Rx, Dagger, в некоторых проектах корутины. Когда приходят новые разработчики, мы регулярно обращаемся за обратной связью, чтобы понимать, что людям нравится и не нравится. И не помню, чтобы сотрудники жаловались, что у нас что-то устарело и предлагали что-то поменять. Мы только успеваем идей накидывать, «давайте попробуем MVI в таком-то модуле», и все начинают генерировать.

Когда человек приходит в нашу команду, он должен быть готов понимать современный стек технологий и уметь ориентироваться в нем. Мы это приветствуем. Это, может быть, даже парадокс: человек идет в финтех, в банковскую разработку, ожидая консервативности, а от него требуют знать, как работают Rx и Kotlin со всеми плюшками. Это, мне кажется, уникальная фишка.

Рост мобильной команды


JUG.ru Group: Вы уже сказали, что решаете проблемы, возникающие при росте команды. А можно конкретный пример?

Михаил: Вот, например. Когда шесть человек в команде проводят ревью пулл-реквестов, по 3-4 человека на пулл-реквесте, они достаточно быстро проходят (особенно в случае, если люди находятся в одном кабинете). Ситуация кардинально меняется, когда сотрудники работают в разных городах и часовых поясах, а команда увеличивается и внутри неё возникают отдельные ячейки (группы разработчиков, объединённые одним тимлидом).

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

Также была проблема с git flow: если сидеть в одной ветке и долго пилить, в это время другая команда может тоже пилить 2-4 фичи в других ветках, а потом всё это к релизным срокам вмёрдживается в ветках, получаем боль в виде merge conflict.

Вторую проблему решали изменением git flow. Начали применять подход trunk-based development, то есть лить сразу в разработческую ветку, отказались от feature-веток. Но так как лить неработающий функционал невозможно, это будет ломать проект, то мы применили подход feature toggle. И тем самым сократили срок выдачи функциональности в релизную ветку на несколько дней. Об этом я подробнее рассказывал в твиттере @mobileunderhood.

Оставалась проблема с ревью. Раньше у нас участвовало порядка 4-5 человек, так как нам важно качество кода, у нас достаточно строгие принципы и подходы к качеству. Мы боялись, что, если уменьшим число ревьюверов, у нас ухудшится качество. При этом на 50 разработчиков, допустим, 30 качественно проводят ревью, а остальные —junior-разработчики или middle, ещё не наработавшие по-настоящему навык.

Поэтому мы пошли по другому пути и придумали формулу «1 лид + 1 старший разработчик + 1 любой разработчик». Сначала применяли эту формулу в рамках команд: допустим, разработчик команды «А» выдаёт пулл-реквест, ставит ревью у куратора и какого-то отдельного разработчика. Пулл-реквестов появляется около 20 штук за полтора дня: если с утра провести ревью всех, то к середине следующего дня будет порядка 20 новых.

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

И мы пошли ещё дальше. Оставили три слота ревьюеров, оставили те же роли (техлид, старший разработчик и любой другой), но не стали заморачиваться, что это должны быть люди из твоей команды. И теперь у нас пулл-реквесты проходят за день, максимум — за полтора. Больше нет долгих историй.

И всё это в комбинации с feature toggle: когда разработчик берётся за фичу, он в первую очередь делает отключающий флаг в коде, чтобы она была на холодном запуске. А потом уже начинает разработку. Всё это проверяется в течение одного дня, не важно, в каком городе команда.

Отдельная история с часовыми поясами. Если мы в Питере делаем пулл-реквест, к вечеру сдаём, то в Новосибирске +4 часа, и пока у нас ещё ночь, они с утра уже смотрят пулл-реквесты. Они уходят с работы — мы получаем их пулл-реквесты и смотрим. Получается постоянный непрерывный поток, в котором часовые пояса работают на руку.

Кирилл: Да, возвращаясь к вопросу о компании: помимо того, что у нас больше 3000 сотрудников, наши центры разработки находятся в трёх городах (Томск, Новосибирск и Санкт-Петербург), и мобильные команды распределены по ним. Немножко сложно, что есть лаг в четыре часа, зато общий рабочий день компании продлевается до 12 часов.

Михаил: Часовые пояса помогают не только в ревью. У нас образована единая Android-разработка, нет такого, что в разных городах все раздельно. Наши команды кросс-функциональны, но объединены по платформенным признакам, как сообщества. Есть стандарты, общие принципы и принятые практики, включая code style и тому подобное. И поэтому, если вдруг возникают проблемы, требующие хот-фикса или других срочных действий, за это могу взяться те, у кого сейчас рабочее время, даже если изначально за этот код отвечали не они. Люди в других городах могут помочь, пока мы спим, и наоборот.

JUG.ru Group: Когда команда разрастается, уже ни один разработчик не может знать кодовую базу целиком или легко уточнить что угодно у сидящего рядом человека. В таком случае, вероятно, возникает еще один челлендж: ведение документации?

Кирилл: Тут стоит сказать вот что: когда мы запланировали рост команды в 10 раз, мы понимали, что не выпустим в 10 раз больше фич (или даже в 7 раз). При таком росте, просто для того, чтобы сохранить прежний уровень качества, требуются дополнительные усилия. И одним из упражнений для новых разработчиков было как раз написание документации перед тем, как начать что-то делать.

Таким образом за короткий срок мы охватили в документации ключевые компоненты приложения. И начали пускать в такие компоненты джунов, потому что с такой документацией уже можно позволить себе код-ревью и тестирование. Это был «отложенный выхлоп» масштабирования.

Сейчас, когда прошёл год, мы подготовили базу, и теперь выводим пришедших год назад разработчиков на полный уровень производительности. Чем дальше мы идём, тем проще становится. На базе созданной документации построили чек-листы со структурой и взаимодействием компонентов, с нашей интеграцией с основными сервисами, и теперь всё это не вызывает паники «я пришёл сюда программировать, а у вас тут энтерпрайз».

Михаил: Дополню Кирилла. После того, как в команде стало больше 30 сотрудников, был период, когда тимлиды и старшие разработчики много времени тратили на одного-двух курируемых разработчиков, потому что постоянно передавали информацию. Мы заранее это поняли и начали действовать. Поэтому в Android выделили отдельное пространство в Confluence и там собрали все принципы, практики и конвеншены по разработке не только в этом проекте, но и в других.

Когда сотрудник приходит в команду, он сначала садится и изучает то, как мы ведём разработку, какие есть правила и практики, какая архитектура проекта. Он даже за код не берется, пока изучает. Затем отвечает на контрольные вопросы. Любое обучение без контрольных вопросов недостаточно эффективное.

Сейчас мы пошли ещё дальше и создаём автоматизированную систему обучения «Галилео». Её суть в нескольких уровнях градации обучения, от принципов разработки и методологий, от архитектурных принципов до принципов языков Kotlin.

После такого погружения половина вопросов отметается. То, что раньше делал лид, сейчас автоматизировано. Когда разработчик выходит непосредственно на производство, через неделю-две, он задаёт уже точечные вопросы, что не составляет проблем. А до этого проблема действительно была.

Я считаю, что даже если проект на 10 человек, всё равно нужно закладывать заранее документацию. Не упарываться по этому поводу, но какие-то принципы заложить. Будет масштабирование — не будет, а в любом случае, когда приходит новый разработчик, документация снимает кучу вопросов и экономит кучу времени куратора.

У нас есть платформенная документация (для Android и iOS), а есть по проектам (бизнес-сценарии и тому подобное).

Кирилл: Мы перешли на некий краудсорсинг. Когда приходит новичок, ему говорят: «Смотри, вот что почитать на первый день, вот на второй». Там настройка, обеспечение различных доступов, инструментарий и так далее. И если человек сталкивается с проблемой, одна из его задач — записать проблему в тот же чек-лист для следующего новичка. Такие вещи преследуют сразу разные цели: мы и готовим документацию для следующих поколений, и обучаем новичка ценности документирования того, что он делает. И у него нет страха перед тем, что написать.

Особо рьяные сразу начинают UML-диаграммы рисовать, что поощряется. Стоит кому-то подать хороший пример, как все вовлекаются. И мы никого не бьём по рукам, так как понимаем, что нужно время, и мы это время даём.

Сторонние библиотеки против внутренних разработок


JUG.ru Group: Хочется еще немного про «внутреннюю кухню» поговорить в разрезе iOS и Android. Насколько понимаем, у вас на iOS политика отказа от third-party решений, а вот Android изначально тоже старались всё писать сами, но потом ушли от этого. Почему?

Михаил: В Android исторически так сложилось. В 2013 году, когда мы делали мобильный банк для карты «Кукруза», в Android-разработке еще почти не было стандартов архитектур и библиотек. Даже сам Google не понимал, куда ему развивать Android. Мы начали разработку, когда ещё не было Android 5, у нас максимальной версией была KitKat 4.4.

Раз нет библиотек, пишем сами. Самописное эффективнее работает, его лучше сопровождать, а чужие косяки исправлять сложнее. Взяли только базовые вещи: например, раньше использовали HTTP-клиент от Volley, а поверх свой API-протокол вроде Retrofit (но менее гибкий). И думали, что мы крутые. Но время шло, стали появляться новые технологии. Dagger стал работать не через рефлексию в рантайме, а через кодогенерацию, появился тот же Retrofit, начали произносить слово «архитектура», появились стандарты и паттерны.
Бизнес приходил и просил что-то сделать, а мы понимаем, что не настолько гибкие, и нужно сначала что-то поменять и порефакторить. С Volley такая проблема была. И мы задумались, что действительно отстаем от времени, потому что вместо бизнес-задач занимались рефакторингом и правками стека технологий.

Также мы начали замечать, что разработчики-инженеры стали менее заинтересованно работать над проектом. Стек старый, в мире хайп, Rx появился, а у нас ничего нет. Сотрудник мог поработать полгода, пожаловаться на скуку и уйти. Это для нас было проблемой. Развитию разработчиков мы сейчас уделяем максимально много времени. Современный стек должен присутствовать не только для решения задач, но и чтобы инженерам было интересно работать и что-то предлагать.

Если компания постоянно занята велосипедами, инженер говорит: «Слушайте, мы тут нашли прекрасную библиотеку, которая сделает лучше», а ему отвечают: «Что-то как-то нет, лучше давай потом», это демотивирует.

Мы полностью отказались от такого подхода, решили максимально использовать мировые практики и библиотеки, чтобы не тратить свое время, а заниматься бизнес-фичами. Как раз тогда начал распространяться Kotlin, мы ещё где-то с версии 1.0 его начали использовать. Начали в себя вбирать клёвые технологии, best practices и подходы к архитектурам. И нам удалось двигаться в ногу со временем и поставить процессы на поток.

Когда пошла история с переписыванием приложения «Денежные переводы» от «Золотой Короны», у нас уже был опыт. И сейчас мы уже занимаемся не техническими долгами в библиотеках и велосипедах, а бизнес-функционалом. У нас один из самых современных стеков и мы его поддерживаем.

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

Кирилл: Мы в iOS, в свою очередь, не то что бы идеологически за велосипеды. У нас прагматичные решения. Нужно что-то сделать — оцениваем, сколько это займёт времени. Если это какие-то фреймворки вроде AFNetworking, сколько может понадобиться времени на реализацию — 40-50 часов в нужном нам объёме (нам же не обязательно реализовывать полностью). Поэтому мы себе такое позволяли.

В прошлом году на Mobius был показательный доклад (на Хабре есть его расшифровка): Феликс Краус говорил о безопасности third-party решений. Он клонил к тому, что не всегда всё, что скачано из стороннего репозитория, является тем, что ты хотел скачать. Но по большей части это означает, что мы должны провести аудит того кода, который мы принимаем себе в проект.



Что касается сетевой подсистемы — кто знает, какая там обработка SSL-сертификатов и хватит ли у нас времени на весь этот аудит, а также навыка реверс-понимания того, что хотел сделать инженер.
Кроме того, мобильная разработка в принципе развивается очень быстро, фреймворки и технологии вспыхивают яркими звездами и так же быстро гаснут. Например, ReactiveCocoa, который был флагманом реактивной разработки 4-5 лет назад. Во-первых, где он сейчас, а во-вторых, что бы случилось с нами, если бы мы на него перешли? Если бы давно и крепко на него подсели, а потом пришёл Swift, то вообще оказались бы в неловкой ситуации.

Если есть провидцы, которые готовы оценить долгосрочность технологии, это очень здорово, но мы не провидцы. На Android в случае с решениями вроде Dagger отличие в том, что это решение от поставщика самой платформы, Google. Если бы Apple выдала что-то такое, мы бы перешли. Ну, она выдала Swift, и мы, конечно, перешли на Swift.

Мы уже 6 лет занимаемся продуктом, а некоторые куски кода вообще из 2011 года. Давайте смотреть на 6-8 лет вперед: где будут фреймворки, сделанные энтузиастами и сообществом? Я не готов гадать на хрустальном шаре, поэтому всё, что мы себе позволили — это SnapKit (потому что в одном файле всё удобно просматривать) и, конечно, сервисные фреймворки — аналитики, системы сбора крэш-логов, это да. Мы не специализируемся в этих областях, и не готовы разрабатывать и поднимать целый сервис, чтобы вести свои сервисные дела.

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

Но давайте смотреть правде в глаза: из последних супернововведений iOS можно выделить только появление Swift. Всё остальное — просто конструкции, которые сделаны инженерами, которые можно повторить, которые не всегда одинаково понимаются разными людьми. Практически все UI-архитектуры, кого ни спроси, каждый видит по-своему.

Swift — это то направление, в котором хотят развиваться бывшие Objective-C разработчики, таких ещё довольно много. Здесь они получают стек технологий, который меняется, возможность для саморазвития, обмена знаниями и о том, что прочитали, узнали, применили на практике…

И когда 3 года назад наша «суперсовременная архитектура» на VIPER перестала удовлетворять решению наших бизнес-задач, мы просто сказали: «окей, у нас будет MVP, похожий на VIPER». И в рамках нашего MVP-подхода решаем сейчас бизнес-задачу со скоростью спринта. Это тот показатель, к которому мы стремимся, и в части производства мы его добились.

Swift и Kotlin


JUG.ru Group: Михаил в @mobileunderhood писал «от Java вообще уходим, переписываем всё на Kotlin». Обычно, даже когда новый код уже пишут на Kotlin, имеющийся на Java меняют очень неторопливо, и он может оставаться в продакшне ещё многие годы. Почему вы решили делать это активнее? И избавляетесь ли так же активно в iOS от кода на Objective-C?

Михаил: Мне Java всегда нравилась. Я всегда её любил, даже сертификат Oracle сдал, и меня она устраивала. Но развитие Java в Android и развитие Java в enterprise — это две разные вещи. И несколько лет назад, когда Kotlin только начинался, использование Java в голом виде без библиотек начало утомлять. Длинные конструкции, мало синтаксического сахара, тут ещё некоторые коллеги с C# накидывали, что у них есть, а у нас нет, это вообще демотивировало. Хотелось писать код, который выполняет логику, и меньше времени тратить на само написание этого кода, использовать больше плюшек, проще понимать и читать код.

Потом появились вещи вроде Lombok. Мне поначалу нравилось, а потом перестало, потому что это какая-то дополнительная библиотека, которая позволяет упрощать код, оборачивать в синтаксический сахар, но это только плагин, а не сам компилятор Java. А Data Class в Kotlin и обычный Java-класс со всеми property и инкапсулирующими методами get/set — это совершенно разные вещи.

И мы довольно давно впервые решили попробовать Kotlin на уровне одного проекта. Мы его написали, некоторые вещи нас смутили — ну, Kotlin и Kotlin, вроде попробовали, нормально, один проект есть, возвращаемся к Java. Вернулись, а через какое-то время я понял, что больше не могу на Java разрабатывать. Всё, она мне надоела, видеть её больше не могу.

Видимо, привык к некоторым синтаксическим вещам, к минимализму кода. И в итоге было принято решение, что нам нужно использовать Kotlin. Лучше воспринимается и читается. Некоторые разработчики были против, но мне кажется, это дело привычки. Ввели практику: новые проекты писать на Kotlin. А старые проекты оставались на Java. Но когда происходили какие-то крупные рефакторинги, то мы переписывали всё на Kotlin. У нас был наработан опыт, чтобы делать это быстро. Это не значит, что мы конвертировали Java-файлы в Kotlin горячими клавишами, а потом исправляли этот код — мы сами переписывали сразу в Kotlin-style.

Осталось буквально два проекта на Java, и там постепенно тоже идёт переход: новые модули пишутся на Kotlin, новые тесты на Kotlin, а старая логика на Java. Если из-за рефакторинга логика меняется — пишем на Kotlin. И в одном из этих проектов прямо сейчас идёт большой рефакторинг. Таким образом, мы поставили миграцию на поток, и после двух лет с Java осталось буквально полтора проекта.

Никто особо не был против. Был некоторый скепсис «Kotlin всего лишь хайп», конечно, но нам очень помогло, когда в Google официально признали Kotlin для Android-разработки, для нас это была просто бомба. Больше не надо было убеждать инженеров: либо ты на волне всех современных разработчиков, либо вне этого рынка.

Кирилл: А со Swift самая первая встреча была такой: мне нужно было сделать небольшую презентацию для одной из наших конференций в Новосибирске, и когда я кусок кода вынес на экран в Objective-C, стало понятно, что при любом размере экрана его не прочитать. И тогда я тот кусок кода для презентации написал на Swift, хотя ещё ни одной «свифтовой» строчки в проекте не было.

Потом мы попробовали Swift на проекте «Золотая Корона – Транспортная карта», который писали с нуля. Обкатали там кое-какие языковые моменты. Было интересно, что мы делаем не так, немножко начали работать в сторону создания своего styleguide. Со второго Swift мы также «переехали» на третий, хлебнули горя, которое тогда всех преследовало.

А если сейчас смотреть на пулл-реквесты, которые у нас есть, там 95% кода на Swift написано. У нас нет сверхзадачи перевести весь имеющийся код с Objective-C на Swift любой ценой. Тем не менее, доля Swift-кода в мобильном приложении «Денежные переводы» составляет 60-65%, мы выпускаем «дайджест свифтизации», в котором рисуем график по файлам Swift / Objective C, по строчкам кода, и в зависимости от релиза и даты всё видно. Доля в 65% не означает, что мы переписали 6 файлов из 10 — в первую очередь рост за счёт новых файлов.

Мы пробовали разные методики перехода, например, в мобильном банке для карты «Кукуруза» сделали однонаправленный переход (то есть наш Swift-код базируется на Objective-С, но мы не переносим конструкции Swift назад в Objective-C). Мы не затаскиваем Swift-функциональность, чтобы таким образом ускорить процесс перехода на Swift. В этом случае, когда действительно припрёт и Objective-C код потребует все зависимости Swift, мы сможем сказать, что компоненту пора полностью перейти на Swift.

Поскольку в продуктах для сервиса «Золотая Корона – Денежные переводы» скорость разработки важнее, чем просто увеличение доли Swift, у нас двунаправленные истории. Они выглядят, может быть, менее красиво, с точки зрения адептов Swift, но раз этот подход дает продукту возможность двигаться быстрее.

Приходили разработчики вообще без знания Swift, язык за две недели осваивается, начинает работать. Иногда боятся, что у нас 60% Swift, но ничего страшного, еще не было случая, чтобы сотруднику не удалось освоить его. Есть противоположные истории — когда узнают, что у нас 40% Objective-C, начинают говорить, что мы ретроградствуем, и нужно сначала всё на Swift переписать, а потом уже фичи пилить. Но тут уже всё индивидуально, и с каждым индивидуально работаем.

Есть смешанные проекты, однонаправленные смешанные проекты, есть чистые проекты на Swift, мы попробовали всё. Всё довольно неплохо работает, серебряной пули нет.

JUG.ru Group: Про Swift и Kotlin говорят «поскольку они похожи, разработчикам для Android и iOS стало удобно заглядывать в код друг друга». А у вас разработчики для разных платформ заглядывают в код друг друга или нет?

Кирилл: Я помню истории, когда Android-разработчики, писавшие ещё на Java, заглядывали в код iOS-разработчиков на Objective-C и наоборот, когда мы писали один из самых сложных компонентов мобильного приложения для карты «Кукуруза» — знаменитый форм-конструктор, пример Backend Driven UI-архитектуры. Там очень интенсивное взаимодействие с бэкендом через определённый протокол, и не сделать одинаково было просто преступно. Мы, конечно, подглядывали.

А теперь у нас разные архитектурные подходы в приложениях, приложения основаны на разных UI-архитектурах. Максимум, где мы можем подглядеть — это бизнес-слой, да и то скорее надо копать в сторону инструментов для тестирования, которые позволяют писать на одном из языков программирования.

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

Михаил: У меня есть примеры. Так как у нас сейчас кросс-функциональные команды, iOS и Android-разработчики практически синхронно делают один и тот же бизнес-функционал на разных платформах, то заглядывают друг другу в код все реже, потому что нечего смотреть, и вся разработка идет ровно.

Но когда кто-то уходит вперёд, при этом, человек понимает, что какая-то большая часть фишки реализована, когда бизнес намекает «посмотрите, как в Android сделано», а аналитика ещё не готова, то бывают случаи, когда разработчики с обеих сторон могут заглянуть и посмотреть, как это сделано. И тут действительно помогает то, что Swift и Kotlin очень похожи.

Я в mobileunderhood делился своим опытом, который у меня был, когда я работал на проекте, в котором у нас была не кросс-функциональная команда, а некий стартап по погашению кредитов. И я в iOS-разработку любил заглядывать, было интересно, как они решают определенные задачи, может даже подкинуть им что-то. И они любили мне накидывать. И мы постоянно, часами могли у доски стоять и разговаривать о том, как выглядит полиморфизм в чистом виде в iOS и Android, как его готовим.

Доходит до обсуждения, что такое абстракция, до каких-то формальных понятий, и это всё довольно весело происходит, а начинается с обычного кода. Ты смотришь и думаешь: а зачем вы это сделали, накладных расходов же много? А мне объясняют, что всё так и задумано, осознанно на это идут, чтобы не тратить 2-3 дня на поиски лучшего решения, если, например, через спринт этот код поменяется. Я думаю: умные ребята, надо и нам иногда так поступать, а не продумывать по пять дней какую-то внутреннюю архитектуру, про которую потом окажется, что она и не нужна.

Я в итоге часто подходил и смотрел код на Swift. На Objective-C тоже смотрел, но Swift мне больше нравится. Хоть на нём и не разрабатывал, но я не думаю, что были бы какие-то сложности написать код. У Android-разработчиков то же самое.


Кирилл: В общем, мы не просто имеем платформенную команду, внутри которой говорим им: «Вы самые лучшие, потому что Apple дал такой инструмент». Ребята из iOS и Android взаимодействуют, вместе участвуют в планированиии, прорабатывают вопросы с системными аналитиками.

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

В дирекции «Предоплаченные карты» у нас были истории, когда бэкендеры зашивались, и тогда Android-разработчики поставили среду, окружение и запилили парочку баг-фиксов, просто чтобы помочь.

Михаил: Вспомнил совсем недавний случай. Там, чтобы клиент был более тонким для нас, бэкенду нужно было больше работы сделать, тогда наши мобильные хитрецы объединились и начали продавливать свою общую идею. Они собрались все вместе, обсудили, как им будет удобно на обеих платформах, пошли к бэкенд-разработчикам и заявили о том, как им удобнее работать, а что нарушает понятие тонкого клиента. Бэкендеры согласились с ними.

Вот если бы одна платформа сказала: «Мы всё сделаем», а вторая отказалась, заявив, что тяжело, то заставили бы вторую как-то договариваться и делать. А так всё вместе получилось. Поэтому синергия, командная разработка действует. И языки и правда помогают в этом. Ведь если Java и Objective-C совсем разные полушария по синтаксису и принципу, то Kotlin и Swift действительно гораздо ближе.

Кирилл: Есть, кстати, примеры, когда ребята становились свитчерами, и даже двойными свитчерами, переходя между платформами. Был один, кто перешёл на iOS, ознакомился, «освифтовался», и ушёл назад в Android. А потом ушёл вообще в DevOps. В этом плане мы тоже открыты, упрощаются такие моменты.

Очень здорово, что ребята хотят профессионального развития, пусть даже в различных плоскостях. Мы даём возможности, а они сами выбирают, в какую сторону хотят развиваться, и почти все ребята у нас мотивированы продуктом, теми задачами, над которыми работают, что очень здорово.

JUG.ru Group: Последний вопрос: а что насчёт кроссплатформенной разработки?

Кирилл: У нас в компании есть находящийся в разработке продукт для Федеральной системы «Город». Вот там для реализации выбран React Native. И мы никакой ревности к этому не испытываем, потому что всегда интересно провести эксперимент и узнать, чем он закончится. Тем более, что у нас есть фронтенд-разработчики, которые хорошо знают своё дело, и интересно попробовать что-то новое и выйти на новые платформы.

Михаил: У нас есть проекты на React Native, но это, скорее, немного не то, потому что его делают фронтенд-разработчики, а iOS и Android-разработчики не сильно пересекаются.

Что касается кроссплатформы, лично я вижу её для небольших команд: когда ресурсов на iOS и Android немного, а проект нужно делать для обеих платформ, почему бы и нет. У нас ресурсов достаточно, а продукты технологически сложные, мы можем себе позволить отдельную разработку для iOS и Android.

Также исторически сложилось, что, когда мы делали большинство своих проектов, ещё не было кроссплатформы. Сейчас, естественно, мы задумались бы о том, чтобы выделить часть бизнес-логики и абстрактной логики в общие модули, потому что никто не любит делать одну работу. Но исторически сложилось, что у нас такого нет.

Тем не менее, это не значит, что так будет всегда. У нас есть много перспективных задач и проектов от бизнеса, есть прототипы, и там рано или поздно мы опробуем либо Kotlin Multiplatform от JetBrains, либо более интересный для нас Flutter.

Кроссплатформа ещё не стандартизировалась в промышленном виде, в котором можно брать и применять её в энтерпрайзе. Судя по общению с кроссплатформенными разработчиками и по их докладам, сейчас постоянно идёт «бег по граблям» и решение проблем. Поэтому можно взять и запилить проект, но чаще всего это будет просто борьба с граблями, и не думаю, что бизнес-фичи можно будет пилить эффективно. Недавно у JetBrains на докладе спрашивали, можно ли вообще в продакшене использовать мультиплатформенную версию Kotlin, и они говорят, что она ещё в экспериментальном виде.

На другом конце есть Flutter, взлетевший в последний год, вот эта штука действительно интересная, Google неслабо вкладывается в это дело. И я знаю, что многие делают пет-проекты на Flutter, которые уже выложены в магазины приложений. И вот это интереснее для нас. Мы немного пресытились Kotlin, с Kotlin/Native придётся собирать много граблей, а вот Flutter с Dart — это совершенно новая штука.

Мы любим всё новое, поэтому кроссплатформенная разработка обязательно будет у нас. Не конкретно в приложении «Денежные переводы», но в каких-то небольших отдельных приложениях она будет.

JUG.ru Group: Спасибо за подробные ответы!




К сожалению, не доступен сервер mySQL