


Правильные именования
Правильные названия улучшают читабельность кода, соответственно экономя время на ознакомление, ведь куда проще использовать метод, когда название примерно описывает его функционал. Так как в коде все состоит из названий (переменные, методы, классы, объекты файлы и т. д.), этот пункт становится очень важным при создании правильного, чистого кода. Исходя из вышесказанного, имя должно передавать смысл, почему, например, переменная существует, что она делает и как используется. Ещё не раз отмечу, что лучшим комментарием для описания переменной служит ее правильное имя.
Именование интерфейсов
Интерфейсы, как правило, используют имена, начинающиеся с большой буквы и написаны в верблюжьем стиле (CamelCase). Раньше при написании интерфейса хорошей практикой считалось добавить префикс I для обозначения его как интерфейса (например, IUserService), но это выглядит весьма уродливо и отвлекает. В таких случая лучше писать без него (UserService), а к реализации его добавить -Impl (UserServiceImpl). Ну или на крайний случай, к его реализации добавить префикс С (СUserService).Названия классов
Так же, как и у интерфейсов, имена пишутся с большой буквы и используют верблюжий стиль (CamelCase). Какой бы ни творился апокалипсис, как бы нb горели сроки, но никогда, запомните — никогда имя класса не должно быть глаголом! Имена классов и объектов должны быть существительными и их комбинациями (UserController, UserDetails, UserAccount, и так далее). Не следует снабжать имя каждого класса аббревиатурой данного приложения, так как это лишь добавит излишнюю сложность (например, у нас приложение User Data Migration, и мы к каждому классу добавим UDM — UDMUserDeatils, UDMUserAccount, UDMUserController).Имена методов
Обычно названия методов начинаются с маленькой буквы, но и они юзают верблюжий стиль (СamelCase). Выше мы говорили про то, что имена классов никогда не должны быть глаголами. Тут же ситуация диаметрально противоположная: наименования методов как раз-таки должны быть глаголами или их сочетаниями с глаголами: findUserById, findAllUsers, createUser и так далее. При создании метода (как впрочем, и переменных и классов), чтобы не запутаться, используйте один подход в именовании. Например, для поиска пользователя метод можно написать как getUserById или findUserById. И ещё: не используйте в названиях методов юмор, ибо шуточку могут и не понять, как и то, что делает этот метод.Названия переменных
В большинстве случаев имена переменных начинаются с маленькой буквы и тоже используют Сamelcase, не считая тех случаев, когда переменная — это глобальная константа. В таких случаях все буквы имени написаны в верхнем регистре и слова разделены нижним подчеркиванием — “_”. При именовании переменных для удобства можно использовать содержательный контекст. Иначе говоря, когда есть переменная как часть чего-то большего — например, firstName, lastName, status — в таких случаях можно добавить приставку, указывающую на объект, частью которого является данная переменная. Например: userFirstName, userLastName, userStatus. Ещё нужно избегать похожих имен для переменных, когда они имеют совершенно разную суть. Часто встречаемые антонимы для переменных:- begin/end
- first/last
- locked/unlocked
- min/max
- next/previous
- old/new
- opened/closed
- visible/invisible
- source/target
- source/destination
- up/down
Короткие имена переменных
Когда у нас есть переменные вида x или n или что-то вроде этого, мы сходу и не увидим намерения человека, писавшего код. Неочевидно, что делает метод n: он требует более вдумчивого осмысления (а это время время, время). Например, у нас есть поле — id ответственного пользователя, и вместо какого-нибудь имени типа — x или просто id, мы назовем эту переменную responsibleUserId, что сходу нам повышает читаемость и осмысленность. Тем не менее, короткие имена вида n имеют место быть в качестве локальных перемен небольших методов, где блок кода с этой переменой — всего лишь пара строк кода, и имя метода прекрасно описывает, что там происходит. Разработчик, увидев такую переменную, понимает её второстепенность и весьма ограниченную область видимости. По итогу есть некая зависимость от длины имени переменных: чем длиннее оно, тем более глобальная переменная и наоборот. Как пример, метод для поиска последнего сохраненного пользователя по дате:
public User findLastUser() {
return findAllUsers().stream()
.sorted((x, y) -> -x.getCreatedDate().compareTo(y.getCreatedDate()))
.findFirst()
.orElseThrow(() -> new ResourceNotFoundException("Any user doesn't exist "));
}
Тут мы используем короткие именования x и y для задания сортировки стрима, и забываем про них.
Оптимальная длина
Продолжим тему длины имён. Оптимальная длина имени — где-то между длиной имен maximumNumberOfUsersInTheCurrentGroup и n. То есть, слишком короткие страдают от недостатка смысла, а слишком длинные растягивают программу, не добавляя читабельности, и их просто лень каждый раз писать. Не учитывая вышеописанного случая, для переменных с коротким именем вида n нужно придерживаться длины примерно 8 -16 символов. Это не строгое правило: скорее как ориентир.Малые различия
Не могу пройти мимо и малозаметных различий в именах, ведь это тоже плохая практика, так как можно просто напутать или потратить много лишнего времени на то, чтобы заметить незначительные различия в именах. Например, различие между InvalidDataAccessApiUsageException и InvalidDataAccessResourceUsageException беглым взглядом сложно обнаружить. Также часто дезинформация может возникнуть при использовании маленьких L и O, ведь их можно легко перепутать с 1 и 0: в некоторых шрифтах различие более очевидное, в некоторых — менее.Смысловая часть
Нужно вкладывать смысловую часть в названия, но не переигрывать с синонимами, так как, к примеру, у UserData и UserInfo фактически один и тот же смысл, и придется немного поковыряться в коде, чтобы понять, какой конкретно объект нам нужен. Избегайте неинформативных слов, к примеру, firstNameString: к чему нам слово string? Разве может быть имя объектом типа даты? Конечно, нет: поэтому просто — firstName. Ещё в качестве примера хотелось бы отметить boolean переменные, например, — flagDelete. Слово flag не несёт никакой смысловой нагрузки. Более разумным было назвать — isDelete.Дезинформация
Также хотелось бы сказать пару слов о неправильных именованиях. Допустим, у нас есть именование userActivityList, и при этом названный так объект имеет не тип List, а какой-нибудь другой контейнер или кастомный объект для хранения. Это может ввести рядового программиста в ступор: уж лучше назвать как-то вроде userActivityGroup или userActivities.Поиск
Одним из недостатков коротких и простых имен является то, что их сложно искать в большом объёме кода, ведь что будет проще найти: переменную с именем name или NAME_FOR_DEFAULT_USER? Конечно же, второй вариант. Нужно избегать в названиях часто встречаемых слов (букв), так это будет лишь увеличивать количество найденных файлов при поиске, что не есть гуд. Хотелось бы напомнить, что за чтением кода программисты проводят больше времени, нежели за его написанием, так что с головой подходите к наименованию элементов вашего приложения. Но что если удачно назвать не получилось? Если название метода плохо описывает его функционал? Тут и выходит на сцену, наш следующий пункт — комментарииКомментарии

Разновидности комментариев
юридические комментарии — комментарии, оставляемые в начале каждого файла с исходным кодом, по юридическим соображениям, как например:
* Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
информативные комментарии — комментарии, представляющие пояснение к коду (предоставляющие дополнительную информацию или намерения данного участка кода.
Как пример:
/* * Объединяет пользователя из бд и пришедшего для обновления * Когда в requestUser поле пустое, оно заполняется старыми данными из foundUser */ private User mergeUser(User requestUser, User foundUser) { return new User( foundUser.getId(), requestUser.getFirstName() == null ? requestUser.getFirstName() : foundUser.getFirstName(), requestUser.getMiddleName() == null ? requestUser.getMiddleName() : foundUser.getMiddleName(), requestUser.getLastName() == null ? requestUser.getLastName() : foundUser.getLastName(), requestUser.getAge() == null ? requestUser.getAge() : foundUser.getAge() ); }
В этом случае можно обойтись и без комментариев, так как название метода и его аргументов вкупе с весьма прозрачным функционалом, сами себя неплохо описывают.
предупреждающий комментарий — комментарий, целью которого является предупредить других разработчиков о нежелательных последствиях какого-то действия (например, почему тест был помечен как @Ignore):
// Слишком долго отрабатывает // Не запускайте, если не располагаете избытком времени @Ignore @Test public void someIntegrationTest() { …… }
TODO — комментарии, которые являются заметкой на будущее, что нужно будет сделать, но по какой-то причине нельзя сделать сейчас. Это неплохая практика, но всё же их нужно регулярно просматривать для удаления неактуальных, чтобы избежать нагромождения.
Примером послужит:
//TODO: Add a check for the current user ID (when will be created security context) @Override public Resource downloadFile(File file) { return fileManager.download(file); }
Тут мы помечаем, что нужно добавить проверку юзера, который скачивает (id которого мы вытащим из security контекста) с тем, кто сохранил.
усиливающий комментарий — комментарий, подчеркивающий важность какого-то обстоятельства, что на первый взгляд может показаться несущественным.
Как пример, кусочек метода, заполняющий тестовую БД, некими скриптами:
Stream.of(IOUtils.resourceToString("/fill-scripts/" + x, StandardCharsets.UTF_8) .trim() .split(";")) .forEach(jdbcTemplate::update); // Вызов trim() очень важен, убирает возможные пробелы в конце скрипта // чтобы при считке и разбивке на отдельные запросы не было пустых
javaDoc — комментарии, которые описывают API определенного функционала для общего пользования. Наверное, самые полезные комментарии, так как с документированным API в разы легче работать, но они также могут устаревать, как и любые другие. Поэтому не забываем, что главный вклад в документацию вносится не комментариями, а хорошим кодом.
Пример вполне обычного метода обновления пользователя:
/** * Обновляет передаваемые поля для пользователя по id. * * @param id id обновляемого пользователя * @param user пользователь с заполненными полями для обновления * @return обновленный пользователь */ User update(Long id, User user);
Плохие сценарии комментариев

бормочущий комментарий — комментарии, которые обычно пишут на скорую руку, смысл которых понятен только разработчику, писавшего их, так как только он видит ту ситуацию с теми нюансами, на которые он и ссылается.
Рассмотрим данный пример:
public void configureSomeSystem() { try{ String configPath = filesLocation.concat("/").concat(CONFIGURATION_FILE); FileInputStream stream = new FileInputStream(configPath); } catch (FileNotFoundException e) { //В случае отсутствия конфигурационного файла, загружается конфигурация по умолчанию } }
Кто загружает эти настройки? Были ли они загружены ранее? Метод предназначен для перехвата исключений и вызова дефолтных настроек? Слишком много вопросов возникает, ответы на которые можно получить лишь углубившись в изучение других частей системы.
избыточный комментарий — комментарий, который не несёт смысловой нагрузки, так как и так понятно что происходит в заданном участке кода (он читается не проще, чем код).
Смотрим пример:
public class JdbcConnection{ public class JdbcConnection{ /** * Журнальный компонент, связанный с текущим классом */ private Logger log = Logger.getLogger(JdbcConnection.class.getName()); /** * Создаёт и возвращает connection с помощью входящих параметров */ public static Connection buildConnection(String url, String login, String password, String driver) throws Exception { Class.forName(driver); connection = DriverManager.getConnection(url, login, password); log.info("Created connection with db"); return connection; }
Какой смысл таких комментариев, если мы и так всё прекрасно видим
недостоверные комментарии — комментарии, не соответствующие истине и лишь вгоняющие в заблуждение (дезинформирующие). Как например:
/** * Вспомогательный метод, закрывает соединение со сканером, если isNotUsing истинно */ private void scanClose(Scanner scan, boolean isNotUsing) throws Exception { if (!isNotUsing) { throw new Exception("The scanner is still in use"); } scan.close(); }
Что в этом комменте не так? А то, что он немножко врёт нам, ведь соединение закрывается, если isNotUsing = false, но никак не наоборот, как нам вещает пометка.
обязательные комментарии — комментарии, которые считают обязательными (Javadoc), но кои по факту иногда бывают излишне нагромождающими, недостоверными и ненужными (нужно задуматься, а нужны ли здесь такие комментарии).
Пример:
/** * Создание пользователя по переданным параметрам * @param firstName имя созданного пользователя * @param middleName среднее имя созданного пользователя * @param lastName фамилия созданного пользователя * @param age возраст созданного пользователя * @param address адресс созданного пользователя * @return пользователь который был создан */ User createNewUser(String firstName, String middleName, String lastName, String age, String address);
Смогли бы вы понять, что делает метод без этих комментариев? Скорее всего да, поэтому комментарии в этом случае стают бессмысленными.
журнальные комментарии — комментарии, которые иногда добавляют в начало модуля, при каждом его редактировании (что-то вроде журнала вносимых изменений).
/** * Записи ведутся с 09 января 2020; ********************************************************************** * 09.01.2020 : Обеспечение соединения с БД с помощью Jdbc Connection; * 15.01.2020 : Добавление интерфейсов уровня дао для работы с БД; * 23.01.2020 : Добавление интеграционных тестов для БД; * 28.01.2020 : Имплементация интерфейсов уровня дао; * 01.02.2020 : Разработка интерфейсов для сервисов, * согласно требованиям прописанным в user stories; * 16.02.2020 : Имплементация интерфейсов сервисов * (реализация бизнес логики связанной с работой БД); * 25.02.2020 : Добавление тестов для сервисов; * 08.03.2020 : Празднование восьмого марта(Миша опять в хлам); * 21.03.2020 : Рефакторинг сервис слоя; */
Когда-то этот проход был оправдан, но с появлением систем управления исходным кодом (например — Git), это стало лишним нагромождением и усложнением кода.
комментарии ссылки на авторов — комментарии, предназначением которых является, указание человека, писавшего код, чтобы можно было связаться и обсудить, как что и зачем:
* @author Bender Benderovich
Опять же, системы контроля версий прекрасно запоминают, кто и когда добавил данный код, и подобный подход излишен.
закомментированный код — код, который был по тем или иным причинам закомментирован. Одна из самых плохих привычек, ибо вы закомментировали и забыли, а у других разработчиков просто не хватит храбрости его удалить (а вдруг это что-то ценное).
// public void someMethod(SomeObject obj) { // ..... // }
Как итог он — скапливается, как хлам. Ни в коем случае нельзя оставлять подобный код. Если уж очень нужно, не забываем опять же про систему контроля версий.
неочевидные комментарии — комментарии, которые излишне сложно описывают что-либо.
/* * Начать с массива, размер которого достаточен для хранения * всех байтов данных (плюс байты фильтра) с запасом, плюс 300 байт * для данных заголовка */ this.dataBytes = new byte[(this.size * (this.deep + 1) * 2)+300];
Комментарий должен объяснять код, а не сам нуждаться в объяснениях. А что тут? Что за «байты фильтра»? При чём здесь +1? Почему именно 300?
- Используйте стили, которые будет легко поддерживать: поддерживать слишком причудливые и экзотические стили надоедает и съедает немало времени.
- Не используйте комментарии в конце строк, относящихся к одиночным строкам: получается большое нагромождение комментов, при этом трудно придумать выразительный комментарий для каждой строки.
- Придумывая комментарий, постарайтесь ответить на вопрос: «почему», а не «как».
- Избегайте сокращений. Как и говорил выше, нам не нужно объяснение для комментария: комментарий и есть объяснение.
- Можно использовать комментарии для пометки единиц измерения и диапазона допустимых величин.
- Располагайте комментарии близко к описываемому ими коду.

ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ