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

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

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

Сравните код для запуска второй активности через нажатие кнопки (из урока 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() даёт основание предполагать, что речь идёт о размере хвоста. Кроме того, метод должен начинаться с глагола.

Или метод 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