воскресенье, 9 октября 2011 г.

Руководство по форматированию исходного кода для Android

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


Использование правил оформления Java-кода
В андроиде при форматировании кода следует придерживаться стандартных правил Java-кодирования, кроме этого необходимо соблюдать дополнительно ещё несколько правил:

Не игнорируйте исключения
Иногда возникает соблазн написать код, который полностью игнорирует исключения вроде этого:
void setServerPort(String value) {
    try {
        serverPort = Integer.parseInt(value);
    } catch (NumberFormatException e) { }
}
Никогда не надо так делать. Вы можете быть уверены, что ваш код никогда не столкнется с этой ошибкой, или вы можете считать, что сама ошибка не важна, но не обращая внимания на исключения, как в примере выше, вы создаете «мины» в коде для тех, кто будет пользоваться вашим кодом. Вы должны принципиально обрабатывать любые исключения в коде. Специфичность обработки исключений - ваше дело и она может варьироваться от случая к случаю, но важно чтобы она была.
Если кто-нибудь ставит пустой обработчик catch, он должен испытывать чувство ужаса за свои действия и стыд. Конечно есть ситуации, когда это,- фактически правильное решение, но в языке Java вы должны все равно ощущать чувство ужаса(Джеймс Гослинг)
Возможные альтернативы (в порядке предпочтения).
1. Сделайте, чтобы метод не обрабатывал возникающее в нем исключение, а выбрасывал его наверх:
void setServerPort(String value) throws NumberFormatException {
    serverPort = Integer.parseInt(value);
}
2. Бросьте новое исключение, соответствующее уровню абстракции в данной ситуации.
void setServerPort(String value) throws ConfigurationException {
    try {
        serverPort = Integer.parseInt(value);
    } catch (NumberFormatException e) {
        throw new ConfigurationException("Port " + value + " is not valid.");
    }
}
3. В обработчике исключения устанавливайте значение по умолчанию.
/** Set port. If value is not a valid number, 80 is substituted. */
void setServerPort(String value) {
    try {
        serverPort = Integer.parseInt(value);
    } catch (NumberFormatException e) {
        serverPort = 80;  // default port for server 
    }
}
4. Можно перехватить исключение и бросить новое - RuntimeException, но это опасно: так надо поступать, если вы уверены, что если это ошибка приводит к некорректному завершению вашей программы.
/** Set port. If value is not a valid number, die. */
void setServerPort(String value) {
    try {
        serverPort = Integer.parseInt(value);
    } catch (NumberFormatException e) {
        throw new RuntimeException("port " + value " is invalid, ", e);
    }
}
Обратите внимание на то, что исходное исключение передается в конструктор для исключение RuntimeException. Если ваш код компилируется под Java 1.3, то вам необходимо просто опустить исключение, которое стало следствием ошибки.

5. Последнее, если вы уверены, что на самом деле игнорирование исключения безопасно, то вы можете всё таки его игнорировать, но вы должны в таком случае хорошо прокомментировать его:
/** If value is not a valid number, original port number is used. */
void setServerPort(String value) {
    try {
        serverPort = Integer.parseInt(value);
    } catch (NumberFormatException e) {
        // Method is documented to just ignore invalid user input.
        // serverPort will just be unchanged.
    }
}

Не перехватываете общие исключения
Иногда возникает соблазн полениться при ловле конкретно исключения и сделать что-то вроде этого:
try {
    someComplicatedIOFunction();        // may throw IOException 
    someComplicatedParsingFunction();   // may throw ParsingException 
    someComplicatedSecurityFunction();  // may throw SecurityException 
    // phew, made it all the way 
} catch (Exception e) {                 // I'll just catch all exceptions 
    handleError();                      // with one generic handler!
}
Не следует так делать. Почти во всех случаях нецелесообразно ловить общее исключение. Это очень опасно, потому что возникшее исключение, возможно вы никогда и не предполагали (например: RuntimeExceptions как ClassCastException) и оно в конечном итоге может быть поймано только на уровне обработки ошибок приложения, так как общее исключение скрывает «неудачные» обработки исключений вашего кода. Это означает, что если кто-то добавит новый тип исключений в вызываемый вами код, компилятор не поможет вам понять, что происходит с работой программы, и что исключение необходимо обрабатывать по-другому, а не в таком общем обработчике. Обычно ведь, обработка различных типов исключений одним и тем же способом, так или иначе невозможна.
Есть редкие исключения из этого правила: определенный тестовый код и код верхнего уровня, где вы хотите перехватить все виды ошибок (чтобы они не отображались в пользовательском интерфейсе, или чтобы сохранить работоспособность). В этом случае вы можете перехватывать общие исключения (или ошибки) и обрабатывать их надлежащим образом, но вам надо хорошо подумать, прежде чем делать так, кроме этого необходимо тщательно откомментировать, почему это безопасно в этом месте.

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

Полностью квалифицируйте импорт
Если вы хотите использовать класс Bar из пакета Foo, Есть два возможных пути для импорта:
import foo.*; 
Плюсы: потенциально уменьшает количество операторов импорта.
import foo.Bar; 
Плюсы: делает очевидным то, что класс действительно используются. Делает код более читабельным для сопровождающих его программистов.
Решение: Используйте последний способ для импорта любого кода в андроиде. Явное исключение следует делать для стандартных библиотек Java (java.util.*java.io.* и др.) и кода юнит-тестов (junit.framework.*)

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

Правила и стиль Java
Используйте стандартные комментарии в стиле Javadoc
Каждый файл должен иметь в начале copyright. Затем должны идти строки операторов импорта и пакета, причем, каждый блок должен отделяться пустой строкой. И, наконец, должна идти декларация класса или интерфейса, в виде Javadoc-комментария/описания того, что класс или интерфейс делает.
/*
 * Copyright (C) 2010 The Android Open Source Project 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at 
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and 
 * limitations under the License.
 */

package com.android.internal.foo;

import android.os.Blah;
import android.view.Yada;

import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * Does X and Y and provides an abstraction for Z.
 */

public class Foo {
    ...
}
Каждый класс и нетривиальный публичный метод, который вы пишете должен содержать Javadoc-комментарий: по крайней мере одно предложение, описания того, что класс или метод делает. Это предложение следует писать от 3-го лица.
Примеры:
/ ** Возвращает корректно округленное положительное значение квадратного корня из double. * / 
static double sqrt(double a) {
    ...
}
или
/ ** * Создает новую строку путем преобразования указанного массива байтов, используя кодировку по умолчанию * / 
public String(byte[] bytes) {
    ...
}
Не нужно писать документацию для тривиальных сеттеров и геттеров, такие как setFoo(), если ваш Javadoc-комментарий выглядил бы так: "устанавливает значение Foo", смысл от этого нулевой. Конечно, если метод делает что-то более сложное (например, содержит ограничения или имеет какой-нибудь важный побочный эффект), то вы обязаны продокументировать его, так же надо комментировать тогда, когда не очевидно, что свойство "Foo" означает.
Каждому методу, который вы пишете, будь он публичный или нет, полезно поставить Javadoc-комментарий. Публичные методы являются частью API и поэтому обязательно требуют Javadoc-комментариев.
Андроид в настоящее время не соблюдает определенного стиля для написания Javadoc-комментариев, но вы должны следовать соглашению Sun о Javadoc-комментариях.

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

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

Область видимости переменных
Видимость локальных переменных должно быть сведена к минимуму (Effective Java, пункт 29). Поступая таким образом, вы увеличиваете читаемость и ремонтопригодность вашего кода и уменьшаете вероятность ошибок. Каждая переменная должна быть объявлена ​​в самом внутреннем блоке, который охватывает все случаи использования этой переменной.
Локальные переменные должны быть объявлены в точке их первого использования. Почти каждое объявление локальной переменной должно содержать её инициализацию. Если вы еще не имеете достаточно информации для нормальной инициализации переменной, вы должны отложить её объявление.
Единственным исключением из этого правила является блок try-catch. Если переменная при инициализации является возвращаемым значением метода, который бросает checked-исключение, она должна быть инициализирована внутри блока try-catch. Если значение должно быть использовано за пределами этого блока, то она должна быть объявлена ​​до блока try, там где она пока не может быть разумно инициализирована, например:
// Instantiate class cl, which represents some sort of Set 
Set s = null;
try {
    s = (Set) cl.newInstance();
} catch(IllegalAccessException e) {
    throw new IllegalArgumentException(cl + " not accessible");
} catch(InstantiationException e) {
    throw new IllegalArgumentException(cl + " not instantiable");
}
// Exercise the set 
s.addAll(Arrays.asList(args));
Но даже этот случай можно избежать путем инкапсуляции  try-catch блока в отдельный метод:
Set createSet(Class cl) {
    // Instantiate class cl, which represents some sort of Set 
    try {
        return (Set) cl.newInstance();
    } catch(IllegalAccessException e) {
        throw new IllegalArgumentException(cl + " not accessible");
    } catch(InstantiationException e) {
        throw new IllegalArgumentException(cl + " not instantiable");
    }
}
...
// Exercise the set 
Set s = createSet(cl);
s.addAll(Arrays.asList(args));
Счетчики должны объявляться в параметрах цикла, если нет веских причин делать иначе:
for (int i = 0; i < n; i++) {
    doSomething(i);
}
и
for (Iterator i = c.iterator(); i.hasNext(); ) {
    doSomethingElse(i.next());
}
Порядок импортов
Список импортов должен состоять из трех частей: 
  1. Android-импортов;
  2. Импорт от третьих лиц (com,junit, net,org) ;
  3. Java и javax.

Кроме того IDE должна быть настроена так чтобы: 
  • Импорты были в алфавитном порядке в каждой группе, большие буквы должны быть раньше строчных (например, импорт начинающийся на Z должен идти до импорта на a). 
  • Каждая крупная группа импортов должна быть отделена пустой строкой: (android, com,junit, net,org, java, javax). 

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

Использование пробелов для отступов
Используйте четыре пробельных символа для выделения блоков, не используйте символ табуляции. Это может стать проблемой для совместимости вашего кода. Используйте 8 пробельных символов для переноса строк, включая вызовы функций и инициализации. Например, так правильно:
Instrument i =
        someLongExpression(that, wouldNotFit, on, one, line);
а так неправильно:
Instrument i =
    someLongExpression(that, wouldNotFit, on, one, line);
Соглашение по именованию полей 
Имена приватных, нестатических полей должны начинаться с прописной m. Статические имена полей начинаются с маленькой s. Остальные поля начинаются с прописной буквы. Публичные статические финализированые поля (константы) пишутся ЗАГЛАВНЫМИ_БУКВАМИ_СО_ЗНАКОМ_ПОДЧЕРКИВАНИЕ Например:
public class MyClass {
    public static final int SOME_CONSTANT = 42;
    public int publicField;
    private static MyClass sSingleton;
    int mPackagePrivate;
    private int mPrivate;
    protected int mProtected;
}
Используйте стандартный стиль оформления блоков кода
Фигурные cкобки не ставятся на новую строку, они идут на одной строке с кодом, расположенным перед ними:
class MyClass {
    int func() {
        if (something) {
            // ...
        } else if (somethingElse) {
            // ...
        } else {
            // ...
        }
    }
}
Скобки должны охватывать ветки условий, за исключением того, если всё условие вместе с веткой умещается в одной строке, тогда вы можете (но не обязаны) обойтись без скобок. То есть, так правильно:
if (condition) {
    body(); 
}
и так правильно:
if (condition) body();
а вот так уже нет:
if (condition)
    body();  // bad!
Предельная длина строки кода
Каждая строка текста в ваш кода должна быть не более 100 символов. Было много дискуссий по поводу этого правила, но решение осталось: 100 символов это максимум. Исключение: если строка содержит комментарий в виде примера команды или буквальный URL длиной более 100 символов, эта линия может быть длиннее 100 символов для простоты копирования в буфер обмена и вставки. Исключение: строки импорта могут переходить за 100 символов, потому что люди редко смотрят на их. Так же это правило упрощает инструменты для написания кода.

 Стандартные аннотации Java
Аннотации должны быть написаны до других модификаторов. Простые аннотации (например, @Override) могут быть написаны на одной строчке с кодом. Если есть несколько аннотаций, или параметризованные аннотации, они должны быть перечислены так, чтобы каждая была единственной в строке и они были бы в алфавитном порядке. Стандартная практика для Android это три предопределенные аннотаций: 
  • @Deprecated: @Deprecated аннотация должна использоваться всякий раз, когда использование элемента не рекомендуется. Если вы используете @Deprecated аннотации, вы также должны использовать @Deprecated теги Javadoc и альтернативные правила для именования полей, кроме того, помните, что @Deprecated метод все еще ​​должны работать. Если вы видите, старый код, который имеет теги @Deprecated Javadoc, пожалуйста, добавьте аннотацию @Deprecated;
  • @Override: аннотацию @Override надо использовать всякий раз, когда метод переопределяет декларацию или реализацию от супер-класса. Например, если вы используете тег Javadoc @inheritdocs, и наследуете свой класс из класса (а не реализуете интерфейс), необходимо также аннотировать, что метод переопределяет метод родительского класса. 
  • @SuppressWarnings: аннотацию @SuppressWarnings следует использовать только в условиях, когда невозможно устранить предупреждение. Если тест передает предупреждение "невозможно устранить", аннотация @SuppressWarnings должна использоваться для того, чтобы все предупреждения отражали реальные проблемы в коде. Когда аннотация @SuppressWarnings является необходимой, она должна иметь префикс-комментарий TODO, поясняющий почему невозможно устранить предупреждение. Это, как правило, используется для отметки плохого класса, который имеет неудобный интерфейс. Например:

// TODO: The third-party class com.third.useful.Utility.rotate() needs generics 
 @SuppressWarnings("generic-cast")
 List blix = Utility.rotate(blax);
Когда встречается аннотация @SuppressWarnings, код должен быть переписан, чтобы изолировать элементы с такой аннотацией. 

Использование сокращений
Исправляйте аббревиатуры и сокращения, слова в именовании переменных, именование методов и классов. Имена должны быть гораздо более читабельные: 
Хорошо: XmlHttpRequest, XMLHTTPRequest, getCustomerId, getCustomerID
Плохо: class Html, class HTML, String url, String URL, long id, long ID.
И JDK и код андроида очень противоречив в отношении сокращений, поэтому, практически невозможно найти согласованый код. Более подробно смотрите Effective Java Пункт 38 и Java Puzzlers номер 68. Использование TODO-комментариев Используйте TODO комментарии для кода, который является временным, краткосрочным решением, или достаточно хорош, но не является идеальным. Такой комментарий должен включать строку TODO в верхнем регистре, за которым следует двоеточие:
// TODO: Remove this code after the UrlTable2 has been checked in.
и
// TODO: Change this to use a flag instead of a constant.
Если ваш TODO имеет вид "В будущем что-то сделать", то убедитесь, что вы вписали очень конкретные даты ("Пофиксить к ноябрю 2005 года"), или очень конкретному событию ("переместить этот код после внедрения протокола V7 "). 

Умеренное логгирование
Хотя логгирование необходимо, оно значительно снижает производительность и быстро теряет свою полезность, если оно несжато и не кратко. Логгирование объектов обеспечивает пять различных уровней ведения журнала логов. Ниже приведены различные уровни и когда и как они должны использоваться. 
  • ERROR: этот уровень логгирования следует использовать, когда произошло что-то фатальное, т.е. что будет иметь видимые последствия пользователю и их нельзя будет исправить без явной потери данных или деинсталляции приложения или форматирования телефона или его перепрошивки. Этот уровень всегда записываются в журнал логов. В вопросах отладки и логгирования, данные лога помеченные ERROR-уровнем, как правило, хорошие кандидаты на передачу на сервер, который занимается сбором статистических данных об ошибках;
  • WARNING: Этот уровень логгирования должен использоваться, когда случилось что-то серьезное и неожиданное, т.е. то что будет иметь видимые пользователю последствия, но, скорее всего, данная ситуация может быть исправлена без потери данных, выполняя некоторые явные действия, начиная от ожидания или перезапуска приложения и заканчивая повторной загрузки новой версии приложения или перезагрузки устройства. Этот уровень всегда записывается в журнал. Такие данные также могут рассматриваться как отчеты для сбора статистических данных;
  • INFORMATIVE: Такой уровень логгирования должен быть использован, когда произошла необязательно ошибка, а какая-нибудь интересная ситуация. Этот уровень всегда записываются в журнал логгов. 
  • DEBUG: Этот уровень логгирования должен быть использован для дальнейшего анализа того, что происходит на устройстве, применяется для расследования и отладки неожиданного поведения или непредусмотренных ситуаций в приложении. Вы должны писать в лог только необходимую вам информацию о том, что происходит в вашем компоненте. Если ваш отладочный лог доминируют над системным, то вам, вероятно, следует использовать уровень ведения лога VERBOSE. Этот уровень будет работать и на сборках с меткой release, и поэтому должен быть окружен блоками if (LOCAL_LOG) или if (LOCAL_LOGD) , где LOCAL_LOG [D] определяется в вашем классе или компоненте, так чтобы была возможность отключить весь уровень DEBUG-логирования, внутри не должно быть никакой логики приложения. Все строки кода, которые пишут в лог должны быть помещены внутрь блока if (LOCAL_LOG). Логгирование не должно быть вынесено за пределы метода в котором оно актуально. Существует код, который использует блоки if (localLOGV). Это считается приемлемым, хотя имя флага о логгировании не является стандартным.
  • VERBOSE: Этот уровень логгирования используется для всего остального. Этот уровень будет входить только в отладочные сборки и должен находится в блоке if (LOCAL_LOGV) или эквивалентном. Весь такой код будет вырезан из сборки релиза. 

Примечания: 
  • Любой уровень логгирования кроме VERBOSE, предполагает запись лога только один раз, если это возможно: в пределах одной цепочки вызовов функций и только в самой внутренней функции, в других местах можно только добавлять необходимую информация, если это существенно помогает изолировать возникшую проблему. 
  • Сообщение отличное от уровня VERBOSE в цепочке вызовов, но на более низком уровне абстракции, которое сообщает о недопустимом значении, поступающее на следующий уровень абстракции должно выводиться только в режиме DEBUG-отладки, и только если этот лог обеспечивает информацию, которая никаким иным образом не связана с вызывающим методом. В частности, нет необходимости описывать ситуацию, когда она - исключение (исключение итак содержит всю необходимую информацию), или ситуация описывается кодом ошибки. Это особенно важно при взаимодействии фраемворка андроида и приложений, а также ситуаций, вызванных другими приложениями, которые правильно обрабатываются стеком андроида, поэтому логгирование должно происходить только при отладке. 
  • В ситуациях, когда логгирование, вероятно, произойдет много раз,возможно стоит реализовать на него некоторые ограничения для предотвращения переполнения журнала логов большим количеством дубликатов(или очень похожих сообщений). Потеря подключения к сети считается общей проблемой и не должна логгироваться. 
  • Потеря сетевого подключения, если при этом есть последствия в приложении должно быть залоггировано на уровнях DEBUG или VERBOSE (в зависимости от последствий ситуации, если они очень серьезны, то могут войти и в релиз приложения). 
  • Сообщения файловой системы для или от имени приложения не должны записываться на уровнях выше, чем INFORMATIVE.
  • Неверные данные, приходящие из любого ненадежного источника (в том числе данные из любого файла в общем хранилище, или данные, поступающие через любые сетевые соединения) считаются ожидаемыми и не должны вызвать какой-либо записи в логи на уровнях отличных от DEBUG (для того чтобы максимально ограничить вывод в лог).
  • Имейте в виду, что оператор конкатенации при работе со строками неявно создает объект StringBuilder с размером буфера по умолчанию (16 символов) и, возможно, довольно много временных объектов типа String, т.е. явное создание объекта StringBuilders не дороже (а, возможно и дешевле ), чем полагаться на оператор '+'. Также имейте в виду, что код, вызывающий Log.v() остается и выполняется в сборке с пометкой релиз, в том числе создаются объекты строк, даже если журналы не читаются.
  • Любое сообщение в лог, которое может быть прочитано другими людьми и будет доступна в релизах должно быть кратким и простым в формулировке, при этом отчетливо передавать суть. Это правило распространяется на все уровни логгирования, кроме уровня DEBUG. 
  • Везде, где это возможно, логгирование должно умещаться в одну строку, это порядком 80-100 символов, сообщения в лог длиной более, чем 130-160 символов (включая длину тега) следует избегать. Сообщения об успешных операциях добавляются в лог с уровнями не выше VERBOSE. 
  • Временное логгирование, который используется для диагностики ситуаций, которые трудно воспроизвести должно вестись на уровнях DEBUG или VERBOSE, и должно быть заключено в блоки, которые можно легко отключить при компиляции.
  • Будьте внимательны к безопасности логгирования,- утечек личной информации, следует избегать. Приватную информацию в логах надо обязательно избегать. Это особенно важно при написании кода фраемворков. 
  • Никогда не надо использовать System.out.println() (или printf() для нативного кода). Вызовы System.out и System.err попадают в /Dev/null, так что ваши попытки вывода информации не будут иметь никаких видимых эффектов, но все строчки это кода будут по-прежнему запускаться на выполнение. 
  • Золотое правило логгирования заключается в том, что ваши данные не должны необоснованно выталкивать данные других приложений из буфера лога, так же, как другие не должны вытеснять ваши сообщения. 

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

Стиль для написания Javatests
Придерживайтесь договоренности о наименовании тестовых методов. При выборе названия методов тестов, вы можете использовать символы подчеркивания для выделения того, что проверяет тест от конкретного варианта теста. Этот стиль позволяет легче увидеть то, что подвергается тестированию. Например:
testMethod_specificCase1 testMethod_specificCase2



void testIsDistinguishable_protanopia() {

    ColorMatcher colorMatcher = new ColorMatcher(PROTANOPIA)

    assertFalse(colorMatcher.isDistinguishable(Color.RED, Color.BLACK))

    assertTrue(colorMatcher.isDistinguishable(Color.X, Color.Y))

}

Перевод официального руководства google

Комментариев нет:

Отправить комментарий