Разработчики пишут много кода, очень много. И я задумался, как сделать так, чтобы писать код быстрее. Надо научится быстрее его набирать? Или может делегировать его написание другим разработчикам? Хороший выход, но какое будет качество кода? Я решил разобраться, какие есть инструменты для ускорения написания кода. Из этой статьи вы узнаете, как писать больше кода или быстрее, используя инструменты, генерацию кода и даже AI технологии.

Если вам интересно следить за самыми последними новостями Android разработки и получать подборку интересных статей по этой тематике, тогда вам стоит подписаться на Телеграм-канал Android Broadcast и мой YouTube канал "Android Broadcast"

Генерация кода

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

Annotations Processor / KAPT

Самый известный способ генерации кода, про который может вы не знаете, но скорее всего используете - Java Annotation Processing (APT), в Kotlin коде вы его используете через KAPT. Эту технологию используют Dagger, Hilt, Room и др. популярные библиотеки. Её суть сводится к тому, что вы добавляете аннотации в своём коде, а в момент компиляции кода специальный процессор анализирует их и на основе полученной информации генерирует код. Вроде бы всё просто, но минусов у такого подхода хватает:

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

  • Сложность написания процессора аннотаций

  • APT позволят только генерировать новый код. Существующие Java классы модифицироваться не могут.

Java? Верно, Java! Ведь APT это механизм языка от Oracle. Поэтому в Kotlin, чтобы он работал, надо использовать KAPT - специальную надстройка над APT для Kotlin кода, которая сначала генерирует Java стабы, затем подкидывает компилятору Java и только тогда происходит работа процессора аннотаций. В итоге получаем Java код в Kotlin проектах + дополнительное влияние на время сборки.

// Оригинальный Kotlin класс
@Module
class Module {

  @Provides
  fun provideData(): Data = Data()
}
// Java стаб, генерируемый kapt для передачи в apt
@Module
class Module {

  @Provides
	public Data provideData() {
		throw Error() // тело функции неважно для apt
	}

}

Конечно же, большой плюс технологии в том, что код не использует рефлексии, поэтому быстро работает в рантайме (если, конечно, разработчики не накосячат), а также такой код может быть оптимизирован R8 или ProGuard, что позволяет его защитить и дополнительно оптимизировать.

Есть способы оптимизировать скорость работы с Dagger во время разработки. У меня есть про это видео.

Чтобы ваша IDE могла работать шустрее и не предлагала вам в автодополнение сгенерированный код, вам надо добавить папки с этим кодом из индекса. Как это сделать, вы найдете здесь. ВАЖНО! Делайте это только в том случае, если вам не нужен поиск по сгенерированному коду!

Kotlin Symbol processing

Если вы зайдете на страницу KAPT, то увидите, что он уже официально помечен как deprecated и не будет поддерживаться. APT оказалось неплохим решением, чтобы избавиться от рефлексии, но с ростом проектов и переходом на Kotlin выявились огромные проблемы технологии. Google прислушались к ним и создали Kotlin Symbol Processing (KSP). Технология схожа с принципами работы APT, но отличается в том, что она работает с Kotlin кодом и генерирует его. Т.е. все дополнительные шаги из KAPT для совместимости с Java делать больше не нужно, что уже на бумаге обещает скорость генерации кода выше. По заявлениям разработчиков получается добиться уменьшения времени генерации кода по сравнению с APT до 2 раз!

Также плюсом KSP является то, что она построена на основе плагинов Kotlin компилятора, т.е. есть дополнительный уровень, где она может быть оптимизирована в будущих версиях без вас.

Минус для авторов процессоров кода — вам придется заново писать генерацию кода на основе KSP! Вы можете спросить, как много библиотек уже адаптировали KSP? Удивитесь, но довольно много. Например, её поддержкой занимаются авторы Room и Moshi, a для Dagger - это основной приоритет (issues на GitHub). Возможно, когда вы читаете эту статью, то эти библиотеки уже полностью поддерживают KSP, а вы все еще страдаете от KAPT. По ссылке сможете найти табличку с состоянием поддержки KSP в популярных библиотеках.

Чтобы вы могли работать с KSP, то всё использование библиотеки с аннотациями должно происходить из Kotlin кода

Gradle Plugin

Помимо того, что Gradle собирает наш проект, мы также можем добавить к ним функционал генерации кода, например, вы можете знать несколько таких: ViewBinding или DataBinding, Apollo GraphQL, protobuf, SQLDelight и другие.

Такой подход обычно используется, когда у вас есть информации не из Kotlin/Java, на основе которой надо сгенерировать код. Например, Android XML ресурсы, которые нельзя получить из Java/Kotlin кода без использования Android фреймворка или SQL запросы.

Плагины Kotlin компилятора

Один из новомодных способов генерации кода — плагины для Kotlin компилятора. Они дают вам уникальные возможности. Например, на основе этой технологии работает Kotlin Serialization, KSP и Jetpack Compose. Причем не только на Android, но и на других платформах. Фактически аннотация Compose благодаря Kotlin компилятору приравнивает его к ключевому слову suspend из Coroutine, но от сторонней библиотеки.

Если вы посмотрите итоговый код, вы увидите модифицированную функцию с другими параметрами, чем объявлены в коде.

// suspend функция в Kotlin
suspend fun longOperation() {
    // Что-то делается
}
// Декомпилированный JVM байт код 
public final Object longOperation(Continuation $completion) {
  // Что-то делается
}

Сейчас у технологии есть один минус — она не имеет публичного и стабильного API, фактически любой релиз, даже минорный, требует автора плагина адаптировать его. Например, с такой проблемой сталкиваются пользователи Jetpack Compose, что определенная версия этого декларативного UI фреймворка привязана к определенной версии Kotlin. Просто так обновится на свежую версию языка не получится. Ждем, когда плагины компилятора получат стабильное API, что позволит обновляться без проблем. Насколько я знаю, это завязано на переход на Kotlin IR Compiler, а затем уже приоритетов команды разработки языка.

IDE

Основной инструмент разработчика - это IDE, а в Android-разработке это будет Android Studio или IDEA. Она имеет множество встроенных возможностей, а также можно расширить ее функционал за счет плагинов и не только.

Сode competition

Сможете ли вы назвать пакет, в котором находится Context и ActivityManager? Скорее всего вы это не помните, даже и не знали никогда, потому что автокомплит делает все это за нас. Вроде бы простая функция, которая просто предлагает вам дополнить классы, но без нее будет довольно непросто. Вспомните, как приходится проходить куда-нибудь кодовую сессию и вам дают какой-то онлайн редактор без анализа кода и предложений при наборе каждой буквы. Производительность сразу пропадает, даже без учета стресса. Цена работы автокомплита в IDEA - долгий индекс, но мы уже привыкли к этому. Все равно время сборки проекта дольше. Помимо этого, в IDEA индекс для JDK не выполняется каждый раз, а просто скачивается, вполне возможно потом это станет также работать с библиотеками и Android SDK.

Live Template

Одна из удобных возможностей IDEA - это с помощью сокращений создавать простые конструкции: main функцию, циклы и другое, что вам захочется. Например, с помощью простого ввода psvm вы можете сгенерировать функцию. Такая возможность называется Live template и позволяет вставить какой-то текст в файл, который может содержать
placeholder-ы, которые надо будет заменить на необходимые вам значения. Конечно, можно добавить свои собственные live template, как с нуля, так и на основе существующих. Например, создать шаблон для ViewModel или метод в Retrofit интерфейсе.

Live Templates в IDEA/Android Studio
Live Templates в IDEA/Android Studio

Плагины

IDE знает все про наш проект: код, систему сборки, помимо этого IDE может расширяться за счет плагинов. Плагины могут создавать новые файлы с кодом, модифицировать существующие и вообще сделать много чего полезного. Кажется, я нашел золотой грааль для генерации кода, которая сделает все, что нам нужно, но тут появляются первые но... Для начала порог входа в написание плагинов высок, нужно поддерживать несколько версий API, еще есть свои особенности у Android Studio. Помимо этого, самая надёжная документация, которая у вас есть — исходный код IDEA Community Edition. Так что этот путь подойдет, если разработка и поддержка плагина займет у вас меньше времени, чем вы или ваша команда потратят времени на написание этого же кода руками. Руководство по написанию плагинов для IDEA здесь.

Шаблоны Android Studio

Android Studio имеет свою возможность для генерации кода. Довольна удобная, имеет множество возможностей и пополняется новыми стандартными шаблонами с поддержкой Compose, Material You и др. Проблема в том, что этот механизм нельзя использовать сторонним разработчикам, чтобы добавить собственные шаблоны, точнее эта функция перестала работать в Android Studio 4.1. Есть соответствующий issue, но на момент выхода этой статьи этот способ недоступен. Может, когда вы будете читать эту статью, этот способ заработал и вы сможете воспользоваться этой фичёй IDE от Google.

Шаблоны при создании нового проекта в Android Studio
Шаблоны при создании нового проекта в Android Studio

Geminio от HH

Довольно сильно в написании плагинов и генерации кода продвинулись ребята из HH. Паша Стрельченко сделал много докладов на тему написания плагинов, а также отдельное спасибо Паше за помощь в подготовке этой статьи. Наиболее интересным решением для генерации кода мне показалось Geminio. Это плагин, который на вход принимает шаблоны для кода, авторы называют их рецептами, причем не только отдельных файлов, но это также можно проделывать с несколькими файлами и даже можно сгенерить Gradle модули. Например, Geminio позволит вам эффективно сгенерить feature модуль с набором базовых классов или классы для презентационного слоя, это я про View - ViewModel (или что вы там используете) и др. файлы с кодом.

Большим плюсом Geminio является отсутствие какой-либо необходимости модификации кода плагина. Хранение шаблонов в проекте, что позволит вам их версионировать, и соответственно никакие изменения не пройдут мимо код ревью, а также все актуальные шаблоны будут доставляться команде. Если вам интересно подробнее узнать о Geminio, то на канале HH Tech есть видео про этот плагин и его использование. Рекомендую посмотреть!

AI Code Competition

Я думаю слово AI мы слышим во всех сферах, вплоть что в мобильных ОС эта технология уже давно используется, а также современное железо имеет чипы аппаратного ускорения. Так почему бы нам не начать использовать AI для написания кода. Тем более дочерняя компания Google уже показала нейросеть AlphaCode, которая смогла попасть в топ 54% в выполнение задач в Codeforces. Решались задачи, которые требуют комбинации критического мышления, логики, алгоритмов, кодинга и понимания естественного языка. Неплохой результат как по мне! Думаете есть шанс у программистов потерять работу из-за автоматизации написания кода? Пишите в комментариях!

Ну а пока вы думаете, я расскажу вам про AI технологии, которые призваны не заменить нас, а помогать с написанием кода. Например, делать автодополнение не только на основе индекса, а на основе контекста решаемой задачи. Все, что я буду рассказывать, будет основано на моем небольшом опыте работы их использования в небольшом Android проекте на Kotlin.

Схема работы GitHub Copilot
Схема работы GitHub Copilot

GitHub Copilot - это первое решение, которое я попробовал. Этот AI компаньон для написания кода тренировался на основе кода open source проектов в GitHub. Официально поддержки Kotlin нет, но технология вполне работает и выдает сносные результаты, хотя в какой-то момент начала мне мешать, потому что стала предлагать мне тот код, что я уже успел удалить )

Помимо этого, меня поразила возможность в комментарии написать, что вам нужно сделать, и Copilot сгенерит вам целые функции. Я провел самый простой тест - генерация функции Фиббоначи - и все сделано точно и без проблем. При попытке генерации метода в Retrofit интерфейсе у меня не получилось сформулировать задание так, чтобы получить необходимый результат. Возможно, сказывается то, что полноценной поддержки Kotlin и Android не заявлено и идет текстовый анализ, а не структурный, но тут я не уверен до конца.

За время теста я понял, что основной минус Copilot - это то, что модель учится на коде, который не имеет отношения к вашему проекту и выдать релевантный результат ей уже становится сложнее. Ведь она учится у лучших, а в старых проекта куча легаси ))) Также не всем понравится, что решение работает только при наличии подключения к интернету и куски вашего кода отправляются на сервер. Сколько кода отправляется? Как часто? Непонятно. Это и вызывает самые основные подозрения

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

Из всех решений меня заинтересовало TabNine. Помимо работы только в онлайне, оно может быть self hosted, а также можно натренировать модель на собственной кодовой базе в популярных Git хостингах. Компании, для которых сохранность данных и безопасность доступов критически важна, оценят это решение. Попробуй на своем желтом проекте убедить провести тест этого сервиса и оценить на большом срезе разработчиков из разных команд.

Конечно же, кодинг с AI происходит быстрее, если дополнения в тему и толковые, но авторы всех сервисов указывают на своих сайтах, что они не тестируют предложенный AI код, есть работоспособность или использование deprecated API или библиотек. Так что мы из инженеров-программистов можем переквалифицироваться в инженеров по качеству кода.

Вы можете уже сейчас бесплатно попробовать различные сервисы с AI автодополнением кода. Делитесь своими впечатлениями. Будет супер, если вы напишите размер кодовой базы, какой сервис вы попробовали и результаты.

На этом у меня все. То, что сегодня я рассказал, поможет вам уменьшить кодовую базу и привести код в вашем проекте к заданному стандарту без необходимости выполнения устных договоренностей. Отдельное спасибо Паше Стрельченко за то, что он поделился своим опытом шаблонизации кода в Head Hunter.

Комментарии (2)


  1. Rusrst
    24.05.2023 14:13

    Эх, а dagger там на ksp переедет когда-то? А то уже К2 не за горами.

    Интересный опыт про copilot, я вот chatgpt попробовал, и смешанные ощущения - оно может врать, но может прям гениальные решения предлагать. Тесты им тоже довольно неплохо писать.


    1. kirich1409 Автор
      24.05.2023 14:13

      Переехать Dagger на KSP не так просто, но работы ведутся