Как сделать код на Kotlin более понятным

kotlin

В этой статье я дам несколько советов с примерами, как сделать код на Kotlin более понятным для чтения.

Другие полезные статьи на тему Kotlin:

Практические советы

Используйте require и check:

Используйте функции вместо комментариев:

А лучше — функции-расширения:

Инфиксные функции делают код более легким для чтения:

Делайе функции инфиксными, если:

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

Используйте функции with, apply и also:

Не указывайте тип там, где его можно не указывать:

Исключения:

  • возвращаемый функцией тип слишком сложный, например Map<Int, Map<String, String>>;
  • когда вызываешь функции, не имеющие nullable-аннотации (например, обычные функции Java).

Используйте присваивание при создании функции, состоящей из одного выражения:

Typealias упростит работу со сложными типами:

Используйте метки точности для уточнения типа присваиваемого значения:

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

Применяйте интерполяцию строк, чтобы сделать их более читаемыми:

Используйте оператор ? для возврата управления:

Применяйте тип Sequence для оптимизации обработки очень длинных списков (более 1000 элементов):

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

Проблемы и решения Kotlin

Проб­лема номер 1: let. Мно­гие прог­раммис­ты при­вык­ли исполь­зовать let в качес­тве прос­той и удоб­ной аль­тер­нативы if (x == null):

Так делать не сто­ит. Исполь­зование it — дур­ной тон, потому что мно­жес­твен­ные it могут сме­шать­ся, если в коде появит­ся еще одна подоб­ная лям­бда. Ты можешь поп­робовать испра­вить это с помощью конс­трук­ции imageFile?.let { image ->, но в ито­ге сде­лаешь еще хуже, потому что в той же области видимос­ти появит­ся еще одна перемен­ная, которая ссы­лает­ся на то же зна­чение, но име­ет дру­гое имя. И это имя надо будет при­думать!

На самом деле в боль­шинс­тве слу­чаев испра­вить эту проб­лему мож­но прос­тым отка­зом от let:

С этим кодом все в поряд­ке. Умное при­веде­ние типов сде­лает свою работу, и ты смо­жешь ссы­лать­ся на imageFile пос­ле про­вер­ки как на не nullable-перемен­ную.

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

Как раз здесь и мож­но исполь­зовать let.

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

Или исполь­зовать метод takeIf:

Мож­но даже ском­биниро­вать оба под­хода:

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

На самом деле такие конс­трук­ции толь­ко зах­ламля­ют код. Гораз­до кра­сивее выг­лядит его более пря­моли­ней­ная вер­сия:

А еще луч­ше вынес­ти код кон­фигури­рова­ния объ­екта в отдель­ную фун­кцию:

Проб­лема номер 3: run. Рас­простра­нен­ный при­ем — исполь­зовать фун­кцию run для обрамле­ния бло­ков кода:

Это абсо­лют­но бес­смыс­ленное зах­ламле­ние кода. Оно зат­рудня­ет чте­ние прос­того по сво­ей сути кода:

Ес­ли же кода в бло­ке «если null» боль­ше одной строч­ки, то мож­но исполь­зовать такую конс­трук­цию:

Проб­лема номер 4: with. В дан­ном слу­чае проб­лема не в самой фун­кции with, а в ее игно­риро­вании. Раз­работ­чики прос­то не исполь­зуют эту фун­кцию, нес­мотря на всю ее кра­соту:

При­чин не исполь­зовать ее обыч­но две:

  • ее нель­зя исполь­зовать в цепоч­ках вызовов фун­кций;
  • она пло­хо дру­жит с nullable-перемен­ными.

С этими советами вы сможете сделать код на Kotlin чище, понят­нее и однознач­нее..

Понравилась статья? Поделиться с друзьями:
Добавить комментарий