Android правила оформления кода

Пишем красивый код

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

Я часто получаю письма от пользователей, которые делятся своими листингами. И порой волосы дыбом встают. Некоторые программисты наивно полагают, что свой код они прекрасно понимают и им не нужно писать красиво — мол и так понятно. В своё время я тоже так думал, а потом мучительно вспоминал, что делает та или иная функция в программе, которую писал несколько лет назад. Кроме того, правильная система написания кода помогает разработке, как это ни странно звучит.

Сравните код для запуска второй активности через нажатие кнопки (из урока 5):

А вот реальный пример из письма пользователя, который на основе того урока, писал своё приложение:

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

Вот почему я беру плату за чтение чужих программ — разбор листингов отнимает много времени и сил.

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

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

Используйте говорящие имена

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

Когда вы придумываете имя для переменной, метода, класса и т.д., то подойдите к данному действию ответственно. Не стоит давать имена из непонятного набора символов типа m1, wl, KU, o, p, r, s, t. Представьте себе, что вы даёте имя коту. Вряд ли ему понравится имя m1 или t. Конечно, он сделает вид, что его это не касается, но карма у вас вряд ли повысится. А если вам такое имя дадут родители?

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

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

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

Допустим, мы создали метод getPage(url), который получает какую-то страницу. А откуда получает: из интернета, базы данных, диска? Если из интернета, то может стоит назвать метод downloadPage(url)? Кстати, мы пока не рассматриваем приёмы, связанные со стилем кодирования. Например, для Android имена методов должны начинаться с маленькой буквы, а второе слово с большой. В других языках могут использоваться другие стили, например, в Visual Basic совсем по другому.

Что возвращает метод size()? Метод getTailSize() даёт основание предполагать, что речь идёт о размере хвоста. Кроме того, метод должен начинаться с глагола.

Читайте также:  Как ребутнуть андроид xiaomi redmi

Или метод stop() — мы понимаем, что метод что-то останавливает. Но может есть более подходящие имена, например, kill() или pause() с родственным ему методом resume(). Ищите яркие запоминающие имена-синонимы.

  • send (посылать) — deliver (доставлять), announce (извещать), route (направлять)
  • find (искать) — search (искать), locate (обнаруживать)
  • start (начинать) — launch (запускать), create (создавать), begin (начинать)
  • make (создавать) — create (создавать), setup (устанавливать), build (строить), generate (генерировать)

Избегайте общих имён

Часто разработчики используют имена вроде tmp, retval, foo и т.д. В учебных примерах этот приём вполне допустим, чтобы показать, что это именно учебный пример. В своих программах следует избегать подобной практики. Иначе получается, что автор признаётся, что никак не может придумать имя. Придумайте такое имя, которое описывает назначение или содержание объекта. Тот же retval — совершенно неинформативное имя, которое сообщает, что это возвращаемое значение, что и так очевидно.

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

Здесь tmp хорошо подходит, так как служит для временного хранилища значения. Больше он нигде не используется и чтение кода не вызовет затруднений.

В более сложных примерах использование слова tmp неоправданно и свидетельствует о лени программиста.

Если речь идёт о временном файле, то используйте, например, вариант tmp_file. Одного взгляда на код будет достаточно, чтобы понять, что в выражении используется объект файла:

Сравните с вариантом:

Для итераторов в цикле обычно используют имена i, j, k. Поэтому не стоит использовать подобные имена в других местах вашего кода. С другой стороны и циклах тоже лучше использовать говорящие имена. Иногда это помогает избежать ошибок, особенно во вложенных циклах, когда можно перепутать имена переменных и использовать неправильные индексы для массивов.

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

Переменные, связанные с измерениями

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

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

Аналогично можно поступать и с другими мерами измерений:

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

Стиль кодирования для Android

На официальном сайте для разработчиков есть отдельная страница Code Style Guidelines for Contributors, посвящённая правилам оформления кода для проектов, написанных под Android.

А также есть ещё одна страница правил — Google Java Style

Источник

Рекомендации к стилю кода

Правила языка Java

Правила Java библиотек

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

Правила Java стиля

Программы гораздо проще поддерживать, когда все файлы имеют согласованный стиль. Мы следуем стандартному стилю программирования на Java, определенному Sun в их Code Conventions for the Java Programming Language, с несколькими исключениями и дополнениями. Данное руководство по стилю является подробным и всесторонним, а также широко используется Java сообществом.

В дополнение, мы обязываем использовать следующие правила для кода:

  1. Комментарии/Javadoc: пишите их; используйте стандартный стиль.
  2. Короткие методы: не пишите гигантских методов.
  3. Поля: должны быть вверху файла, или прямо перед методом, который их использует.
  4. Локальные переменные: ограничивайте область видимости.
  5. Импорты: android; сторонние (в алфавитном порядке); java(x)
  6. Отступы: 4 пробела, без табуляций.
  7. Длина строки: 100 символов.
  8. Имена полей: не public и не static поля начинаются с «m».
  9. Фигурные скобки: открывающие фигурные скобки не находятся в отдельной строке.
  10. Аннотации: используйте стандартные аннотации.
  11. Сокращения: используйте сокращения как слова в именах, например, XmlHttpRequest, getUrl() и т.п.
  12. Стиль TODO: «TODO: пишите описание здесь».
  13. Согласованность: смотрите, что находится вокруг вас.
Читайте также:  Android blu ray iso player

Правила языка Java

Не игнорируйте исключения

Возможно, вам захочется написать код, который игнорирует исключения, например:

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

    Перебрасывайте исключения к вызывающему методу.

Выбрасывайте исключения, соответственно вашему уровню абстракции

Перехватите ошибку и замените соответствующее значение в блоке catch<>

  • Перехватите ошибку и выбросьте RuntimeException. Это опасно: делайте это только если вам все равно случится ли эта ошибка.
    Заметьте, что изначальное исключение передается конструктору RuntimeException. Если вы используете компилятор Java 1.3, то опустите исключение.
  • Если вы уверены в том, что игнорирование исключения в этом случае имеет место, то хотя бы прокомментируйте, почему вы так решили.
    Не перехватывайте обобщенные исключения

    Иногда бывает заманчиво полениться с обработкой исключений и написать что-то вроде этого:

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

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

    Альтернативы обобщенным исключениям:

    • Перехватывайте каждое исключение отдельно в блоке catch, после одиночного try. Возможно это неудобно, но всё равно это предпочтительный способ для перехвата всех исключений.
    • Измените ваш код для более гранулированной обработки ошибок с несколькими блоками try. Отделите IO от парсинга, обрабатывайте ошибки отдельно в каждом случае.
    • Перебросьте исключение. Во многих случаях вам не нужно обрабатывать все исключения на текущем уровне, просто позвольте методу перебросить их.

    Помните: исключения — ваши друзья! Не сердитесь, когда компилятор указывает на то, что вы их не отлавливаете.

    Финализаторы

    Что это: Финализаторы — это способ запускать программный код перед тем как объект собирается сборщиком мусора.
    За: могут быть полезны при очистке, в особенности внешних ресурсов.
    Против: нет никаких гарантий того, когда будет вызван финализатор, и, вообще, будет ли он вызван.

    Решение: Мы не используем финализаторы. В большинстве случаев, всё то, что вам нужно от финализатора, вы сможете сделать при помощи обработки исключений. Если вам действительно нужен финализатор, то объявите метод close() и задокументируйте, когда он точно будет вызываться.

    Импорты
    Групповой символ в импортах

    Что это: Когда вы хотите использовать класс Bar из пакета foo, то есть два способа сделать это:

    За #1: Потенциально уменьшает количество возможных операторов импорта.
    За #2: Делает явным то, какой класс на самом деле используется. Делает код более удобочитаемым для тех, кто его поддерживает.

    Решение: Используйте стиль #2 для импорта любого Android кода. Явное исключение делается для стандартных библиотек (java.util.*, java.io.*, и т.п) и для кода модульного тестирования (junit.framework.*).

    Комментарии/Javadoc

    Каждый файл должен иметь объявление об авторских правах в самом начале. Далее идут объявления операторов package и import, причем каждый блок разделяется пустой строкой. За ними следуют объявления класса или интерфейса. Опишите, что делает класс в Javadoc-комментариях.

    Каждый класс и нетривиальный public метод должен содержать Javadoc, по крайней мере с одной фразой, описывающей что он делает. Фраза должна начинаться с описательного глагола 3-го лица. Примеры:

    Вам не нужно описывать Javadoc для тривиальных get и set методов, таких как setFoo(), если ваш Javadoc говорит только «sets Foo». Если метод делает что-то более сложное (например, соблюдение неких ограничений, или если его действия имеют важный эффект вне его самого), тогда его обязательно нужно задокументировать. И если это не просто объяснение того, что означает Foo, то вам также следует его задокументировать.

    Читайте также:  Русификатор для андертейл андроид

    Вообще, любой метод, который вы написали получает пользу от Javadoc, неважно public он или нет. Public методы являются частью API, и поэтому они требуют описания в Javadoc.

    Для написания Javadoc’ов вам следует придерживаться Sun Javadoc conventions.

    Короткие методы

    Методы должны быть небольшими и решающими конкретную задачу настолько, насколько это возможно. Однако, понятно, что иногда большие методы бывают целесообразны, так что нет строгого ограничения на длину метода. Если метод превышает 40 строк, то вам, возможно, стоит подумать о том, можно ли его разбить на части, не нарушив структуры программы.

    Локальные переменные

    Область видимости локальных переменных должна сводиться к минимуму. Делая это, вы улучшаете читаемость и поддерживаемость кода, а также уменьшаете вероятность ошибок. Каждая переменная должна объявляться в самом глубоком блоке, который окружает все возможные места использования переменной.

    Локальные переменные должны объявляться в том месте, где впервые необходимо её использовать. Почти каждая локальная переменная нуждается в инициализаторе. Если вы еще не знаете, как точно инициализировать переменную, то вам следует отложить её объявление, пока вы это не узнаете.

    Существует одно исключение, касательно блока try-catch. Если переменная инициализируется при помощи оператора return метода, который выбрасывает проверяемое исключение, то она должна инициализироваться в блоке try. Если же переменная должна использоваться вне блока try, тогда она объявляется перед ним, неважно, знаете ли вы как её точно нужно инициализировать:

    Но даже этот случай можно обойти при помощи инкапсуляции блока try-catch в методе.

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

    Импорты

    Отступы

    мы используем 4 пробела для блоков. Мы никогда не используем табуляцию. Мы используем 8 пробелов для переноса строк, включая вызовы функций и присваивания, например правильно так:

    Названия полей

    • Не static и не public имена начинаются c «m».
    • static поля начинаются с «s».
    • Другие поля начинаются с буквы нижнего регистра.
    • Поля public static final (константы) пишутся полностью в верхнем регистре, с использованием подчеркивания (ALL_CAPS_WITH_UNDERSCORES)

    Например:

    Фигурные скобки

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

    Мы требуем фигурные скобки для оператора условия. Исключением является, когда оператор условия и его тело помещаются в одну строку. То есть можно писать так:

    Длина строки

    Каждая строка текста в коде должна быть не длиннее 100 символов.
    Исключение: если комментарий содержит пример команд, или URL (удобнее использовать copy/paste).
    Исключение: строки импорта могут быть длиннее 100 символов, так как люди редко на них смотрят. Также это упрощает написание инструментов.

    Сокращения в именах

    Рассматривайте сокращения и аббревиатуры как слова. Имена более удобочитаемы:

    Хорошо Плохо
    XmlHttpRequest XMLHTTPRequest
    getCustomerId getCustomerID

    Этот стиль также применяется, когда сокращение и аббревиатура — это полное имя:

    Хорошо Плохо
    class Html class HTML
    String url; String URL;
    long id; long ID;

    Стиль TODO

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

    Если ваш комментарий имеет вид «В будущем сделать что-то», то убедитесь, что он включает в себя конкретную дату (1 января 2011 года), или конкретное событие «Удалить после выхода версии 2.1».

    Согласованность

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

    Весь смысл рекомендаций к стилю кода в создании общей лексики, чтобы люди концентрировались на том, что они говорят, вместо того как они говорят. Мы представляем глобальные правила стиля, чтобы люди знали эту лексику. Но локальный стиль также важен. Если код, который вы добавляете в файл выглядит резко отличным от того, что был, то это выбросит будущего читателя из его ритма и будет мешать ему понимать структуру. Старайтесь избегать этого.

    Источник

  • Оцените статью