Автор оригинала: Kumar Chandrakant.
1. Обзор
В этом учебнике мы пройдемся по принципам чистого кодирования. Мы также поймем, почему чистый код важен и как этого достичь в Java. Кроме того, мы увидим, если Есть какие-либо инструменты, чтобы помочь нам.
2. Что такое чистый код?
Итак, прежде чем перейти к деталям чистого кода, давайте поймем, что мы подразумеваем под чистым кодом. Честно говоря, не может быть одного хорошего ответа на этот вопрос. В программировании некоторые проблемы достигают всех и, следовательно, приводят к общим принципам. Но тогда, каждый язык программирования и парадигма представляют свой собственный набор нюансов, который обязывает нас принять подобает практике.
В целом, чистый код можно обобщить как код, который любой разработчик может легко прочитать и . Хотя это может звучать как упрощение концепции, мы увидим позже в учебнике, как это создает. Везде, где мы слышим о чистом коде, мы, возможно, встретить некоторые ссылки на Мартина Фаулера. Вот как он описывает чистый код в одном из мест:
Любой дурак может написать код, который компьютер может понять. Хорошие программисты пишут код, который люди могут понять.
3. Почему мы должны заботиться о чистом коде?
Написание чистого кода является вопросом личной привычки столько, сколько это вопрос мастерства. Как разработчик, мы растем на основе опыта и знаний с течением времени. Но, мы должны спросить, почему мы должны инвестировать в разработку чистого кода в конце концов? Мы получаем, что другие, вероятно, будет легче читать наш код, но это стимул достаточно? Давайте выясним!
Принципы чистого кодирования помогают нам достичь многих желаемых целей, связанных с программным обеспечением, которое мы намерены производить. Давайте пройдите через них, чтобы понять это лучше:
- Поддерживается кодовая база : Любое программное обеспечение, которое мы разрабатываем, имеет продуктивную жизнь и в течение этого периода потребует изменений и общего обслуживания. Чистый код может помочь в разработке программного обеспечения, которое легко изменить и с течением времени.
- Легче устранение неполадок : Программное обеспечение может проявлять непреднамеренное поведение из-за различных внутренних или внешних факторов. Это часто может потребовать быстрого поворота с точки зрения исправления и доступности. Программное обеспечение, разработанное с чистыми принципами легче устранения неполадок для проблем .
- Быстрее на борту : Программное обеспечение в течение своего срока службы будет видеть многие разработчики создают, обновляют и поддерживают его, с разработчиками присоединения в разные моменты времени. Это требует быстрее на борту, чтобы сохранить производительность высокой , и чистый код помогает достичь этой цели.
4. Характеристики чистого кода
Кодовые базы, написанные с чистыми принципами кодирования, обладают несколькими характеристиками, которые их отбирают. Давайте рассмотрим некоторые из этих характеристик:
- Сосредоточены : Кусок код должен быть написан для решения конкретной проблемы . Он не должен делать ничего строго не связанного с решением данной проблемы. Это относится ко всем уровням абстракции в кодовой базе, таким как метод, класс, пакет или модуль.
- Простые : Это, безусловно, наиболее важным и часто игнорируются характеристики чистого кода. Программное обеспечение проектирование и реализация должны быть как можно более простыми , которые могут помочь нам достичь желаемых результатов. Увеличение сложности в кодовой базе делает их подверженными ошибкам и трудными для чтения и обслуживания.
- Тестируемые : Чистый код, будучи простым, должен решить проблему под рукой. Это должно быть интуитивно понятным и простым для тестирования кодовой базой, предпочтительно в автоматическом режиме . Это помогает установить базовое поведение базы кода и упрощает его изменение, ничего не нарушая.
Именно это помогает нам достичь целей, обсуждаемых в предыдущем разделе. Полезно начать развиваться с этими характеристиками в виду, по сравнению с рефактором позже. Это приводит к снижению общей стоимости владения для жизненного цикла программного обеспечения.
5. Чистое кодирование на Java
Теперь, когда мы прошли через достаточно фона, давайте посмотрим, как мы можем включить принципы чистого кодирования в Java. Java предлагает множество лучших практик, которые могут помочь нам написать чистый код. Мы будем классифицировать их в разных ведрах и понять, как написать чистый код с образцами кода.
5.1. Структура проекта
Хотя Java не обеспечивает выполнение какой-либо структуры проекта, Всегда полезно следовать последовательному шаблону для организации наших исходных файлов, тестов, конфигураций, данных и других артефактов кода . Maven, популярный инструмент сборки для Java, предписывает конкретную структуру проекта . Хотя мы не можем использовать Maven, это всегда приятно придерживаться конвенции.
Давайте посмотрим некоторые папки, которые Maven предлагает нам создать:
- src/main/java : Для исходных файлов
- src/main/resources : Для файлов ресурсов, таких как свойства
- src/test/java : Для тестовых исходных файлов
- src/test/ресурсы : Для тестовых файлов ресурсов, таких как свойства
Подобно этому, есть и другие популярные структуры проектов, такие как Bazel, предложенные для Java, и мы должны выбрать один в зависимости от наших потребностей и аудитории.
5.2. Конвенция о наименовании
После именования конвенций может пойти длинный путь в принятии нашего кода читаемым и, следовательно, поддерживать . Род Джонсон, создатель Spring, подчеркивает, важность именования конвенций весной:
“… если вы знаете, что что-то делает, вы получили очень хороший шанс угадать название класса Весна или интерфейс для него …”
Java предписывает набор правил придерживаться, когда дело доходит до именования ничего в Java. Хорошо сформированное имя не только помогает в чтении кода, но и многое говорит о намерении кода. Возьмем несколько примеров:
- Классы : Класс с точки зрения объектно-ориентированных концепций является планом для объектов, которые часто представляют реальные объекты. Поэтому имеет смысл использовать существительные, чтобы назвать классы, описывающие их достаточно:
public class Customer { }
- Переменные : Переменные в Java захватывают состояние объекта, созданного из класса. Название переменной должно четко описать цель переменной:
public class Customer { private String customerName; }
- Методы : Методы в Java всегда являются частью классов и, следовательно, обычно представляют собой действие на состояние объекта, созданного из класса. Это, следовательно, полезно назвать методы с использованием глаголов :
public class Customer { private String customerName; public String getCustomerName() { return this.customerName; } }
Хотя мы только обсуждали, как назвать идентификатор в Java, обратите внимание, что есть дополнительные лучшие практики, такие как верблюжья оболочка, которую мы должны соблюдать для читаемости. Там может быть больше конвенций, связанных с именование интерфейсов, enums, константы, а также.
5.3. Структура исходных файлов
Исходный файл может содержать различные элементы. В то время как Java компилятор обеспечивает некоторую структуру, большая часть жидкости . Но соблюдение определенного порядка, в котором помещает элементы в исходный файл, может значительно улучшить читаемость кода. Есть несколько популярных стилей-гидов, чтобы черпать вдохновение из, как один за Google а другой по Весенние .
Давайте посмотрим, как должен выглядеть типичный порядок элементов в исходным файле:
- Заявление о пакете
- Заявления об импорте
- Весь статический импорт
- Весь не статический импорт
- Ровно один класс высшего уровня
- Переменные класса
- Переменные экземпляра
- Конструкторы
- методика
Помимо вышесказанного, методы могут быть сгруппированы в зависимости от их функциональности или . Нет ни одной хорошей конвенции, и идея должна быть решил один раз, а затем следуют последовательно.
Давайте посмотрим хорошо сформированный исходный файл:
# /src/main/java/com/baeldung/application/entity/Customer.java package com.baeldung.application.entity; import java.util.Date; public class Customer { private String customerName; private Date joiningDate; public Customer(String customerName) { this.customerName = customerName; this.joiningDate = new Date(); } public String getCustomerName() { return this.customerName; } public Date getJoiningDate() { return this.joiningDate; } }
5.4. Белые пространства
Мы все знаем, что легче читать и понимать короткие абзацы по сравнению с большим блоком текста. Это не очень отличается, когда дело доходит до чтения кода, а также. Хорошо расположенные и последовательные пробелы и пустые строки могут повысить читаемость кода.
Идея заключается в том, чтобы ввести логические группировки в код, которые могут помочь организовать мыслительные процессы, пытаясь прочитать его. Существует не одно правило принять здесь, но общий набор руководящих принципов и присущие намерения держать читаемость в центре его:
- Две пустые строки перед началом статических блоков, полей, конструкторов и внутренних классов
- Одна пустая строка после многолинейной подписи метода
- Одно пространство, разделяющее зарезервированные ключевые слова, как если бы, ибо, поймать из открытых скобках
- Одно пространство, разделяющее зарезервированные ключевые слова, как и все остальное, поймать от закрытия скобки
Перечень здесь не является исчерпывающим, но должен дать нам подшипник, чтобы возглавить к.
5.5. Отступ
Хотя довольно тривиально, почти любой разработчик будет поручиться за то, хорошо отступный код гораздо легче читать и понимать . В Java нет единой конвенции для отступа кода. Ключевым моментом здесь является либо принять популярную конвенцию или определить частную, а затем последовательно следовать ему по всей организации.
Давайте посмотрим некоторые из важных критериев отступов:
- Типичная передовая практика заключается в использовании четырех пространств, единицы отступов. Обратите внимание, что некоторые руководящие принципы предлагают вкладку вместо пробелов. Хотя нет абсолютной наилучшей практики здесь, ключ остается последовательности!
- Как правило, должна быть крышка над длиной линии, но это может быть установлено выше, чем традиционные 80 из-за больших экранов разработчики используют сегодня.
- Наконец, поскольку многие выражения не вписываются в одну строку, мы должны постоянно их нарушать:
- Метод разрыва вызывает после запятой
- Разбей выражения перед оператором
- Indent обернутые линии для лучшей читаемости (мы здесь, в Baeldung предпочитают два пространства)
Рассмотрим пример:
ListcustomerIds = customer.stream() .map(customer -> customer.getCustomerId()) .collect(Collectors.toCollection(ArrayList::new));
5.6. Параметры метода
Параметры необходимы для методов работы в соответствии со спецификацией. Но, длинный список параметров может сделать его трудным для кого-то, чтобы прочитать и понять код . Итак, где мы должны провести черту? Давайте поймем лучшие практики, которые могут помочь нам:
- Попробуйте ограничить количество параметров, которые принимает метод, три параметра могут быть одним хорошим выбором
- Рассмотрим рефакторинг метода, если он нуждается в большем, чем рекомендуемые параметры, обычно длинный список параметров также указывает на то, что метод может делать несколько вещей
- Мы можем рассмотреть возможность объединения параметров в пользовательские типы, но должны быть осторожны, чтобы не сбросить несвязанные параметры в один тип
- Наконец, хотя мы должны использовать это предложение, чтобы судить о читаемости кода, мы не должны быть педантичный об этом
Давайте посмотрим пример этого:
public boolean setCustomerAddress(String firstName, String lastName, String streetAddress, String city, String zipCode, String state, String country, String phoneNumber) { } // This can be refactored as below to increase readability public boolean setCustomerAddress(Address address) { }
5.7. Твердое кодирование
Значения жесткого кодирования в коде часто могут привести к множественным побочным эффектам. Например, это может привести к дублированию, что затрудняет . Это часто может привести к нежелательному поведению, если значения должны быть динамичными. В большинстве случаев жесткие значения могут быть рефакторингом одним из следующих способов:
- Рассмотрите возможность замены константами или enums, определенными в Java
- Или же замените константы, определенные на уровне класса или в отдельном файле класса
- По возможности замените значения, которые можно выбрать из конфигурации или среды
Рассмотрим пример:
private int storeClosureDay = 7; // This can be refactored to use a constant from Java private int storeClosureDay = DayOfWeek.SUNDAY.getValue()
Опять же, нет строгих руководящих принципов вокруг этого придерживаться. Но мы должны осознавать тот факт, что некоторые из них должны будут прочитать и сохранить этот код позже. Мы должны выбрать конвенцию, которая подходит нам, и быть последовательными об этом.
5.8. Комментарии к кодексу
Код комментарии может быть полезно при чтении кода, чтобы понять нетривиальные аспекты . В то же время следует позаботиться о том, чтобы не включать очевидные вещи в комментарии . Это может раздувать комментарии, что затрудняет чтение соответствующих частей.
Java допускает два типа комментариев: комментарии к реализации и комментарии к документации. У них разные цели и разные форматы. Давайте поймем их лучше:
- Комментарии документации/JavaDoc
- Аудитория здесь — пользователи кодовой базы
- Детали здесь, как правило, реализация бесплатно, сосредоточив внимание больше на спецификации
- Обычно полезно независимо от базы кода
- Комментарии по реализации/блоку
- Аудитория здесь разработчики, работающие над кодовой базой
- Подробная информация здесь специфична для реализации
- Обычно полезно вместе с кодовой базой
Итак, как мы должны оптимально использовать их, чтобы они были полезными и контекстуальными?
- Комментарии должны дополнять только код, если мы не в состоянии понять код без комментариев, возможно, нам нужно рефакторинг его
- Мы должны использовать блок комментарии редко, возможно, чтобы описать нетривиальные дизайнерские решения
- Мы должны использовать комментарии JavaDoc для большинства наших классов, интерфейсов, общедоступных и защищенных методов
- Все комментарии должны быть хорошо сформированы с надлежащей отступом для читаемости
Рассмотрим пример содержательного комментария к документации:
/** * This method is intended to add a new address for the customer. * However do note that it only allows a single address per zip * code. Hence, this will override any previous address with the * same postal code. * * @param address an address to be added for an existing customer */ /* * This method makes use of the custom implementation of equals * method to avoid duplication of an address with same zip code. */ public addCustomerAddress(Address address) { }
5.9. Лесозаготовка
Любой, кто когда-либо положил руки на производственный код для отладки жаждал больше журналов в какой-то момент времени. важность журналов не может быть чрезмерно подчеркнута в развитии в целом и обслуживании в частности .
В Java есть много библиотек и фреймворка для ведения журнала, в том числе SLF4J, Logback. В то время как они делают журнал довольно тривиальным в кодовой базе, необходимо позаботиться о регистрации передового опыта. В противном случае сделали лесозаготовки может оказаться кошмаром обслуживания, а не какой-либо помощи. Давайте рассмотрим некоторые из этих лучших практик:
- Избегайте чрезмерной регистрации, подумайте о том, какая информация может помочь в устранении неполадок
- Выбирайте уровни журнала с умом, мы можем включить уровни журнала выборочно на производстве
- Будьте очень четкими и описательными с контекстуальными данными в сообщении журнала
- Используйте внешние инструменты для отслеживания, агрегирования, фильтрации сообщений журнала для более быстрой аналитики
Рассмотрим пример описательной регистрации с правильным уровнем:
logger.info(String.format("A new customer has been created with customer Id: %s", id));
6. Это все?
Хотя в предыдущем разделе выделяется несколько конвенций форматирования кода, это не единственные, о которых мы должны знать и заботиться. Читаемый и подаемый код может извлечь выгоду из большого количества дополнительных передового опыта, накопленных с течением времени.
Мы, возможно, столкнулись с ними, как смешные аббревиатуры с течением времени. Они по существу захватить обучения как единый или набор принципов, которые могут помочь нам написать лучший код . Однако обратите внимание, что мы не должны следовать за всеми из них только потому, что они существуют. В большинстве случаев выгода, которую они предоставляют, пропорциональна размеру и сложности базы кода. Мы должны получить доступ к нашей базе кода, прежде чем принимать какой-либо принцип. Что еще более важно, мы должны оставаться в соответствии с ними.
6.1. ТВЕРДЫЙ
SOLID является мнемонической аббревиатурой, которая опирается на пять принципов, которые она излагает для написания понятного и сохраняемого программного обеспечения:
- Принцип единой ответственности : Каждый интерфейс, класс или метод, который мы определяем, должны иметь четко определенную цель . В сущности, он должен в идеале делать одно и делать это хорошо. Это фактически приводит к меньшим методам и классам, которые также могут быть тестируемыми.
- Открытый принцип : Код, который мы пишем, в идеале должен быть открыт для расширения, но закрыт для изменения . Это фактически означает, что класс должен быть написан таким образом, чтобы не было необходимости изменять его. Тем не менее, он должен допускать изменения через наследование или состав.
- Принцип замены Лискова : Этот принцип гласит, что каждый подкласс или производный класс должен быть заменяемым для их родительского или базового класса . Это помогает уменьшить связь в кодовой базе и, следовательно, улучшить повторное использования в поперечнике.
- Принцип сегрегации интерфейса : Реализация интерфейса является способом обеспечения конкретного поведения для нашего класса. Тем не менее, классу не нужно реализовывать методы, которые не требуют . Это требует от нас определения меньших, более сфокусированных интерфейсов.
- Принцип инверсии зависимости : В соответствии с этим принципом, классы должны зависеть только от абстракций, а не от их конкретных . Это фактически означает, что класс не должен нести ответственность за создание экземпляров для своих зависимостей. Скорее, такие зависимости должны быть введены в класс.
6.2. СУХОЙ И ПОЦЕЛУЙ
DRY означает “Дон повторить себя”. Этот принцип гласит, что часть кода не должна повторяться по всему программному . Смысл этого принципа заключается в сокращении дублирования и повышении повторного использования. Однако, пожалуйста, обратите внимание, что мы должны быть осторожны в принятии этого слишком буквально. Некоторое дублирование может реально улучшить читаемость и удобство обслуживания кода.
KISS означает “Держите его простым, глупым”. Этот принцип гласит, что мы должны стараться держать код как можно проще . Это позволяет легко понять и поддерживать с течением времени. Следуя некоторым из упомянутых ранее принципов, если мы будем держать наши классы и методы сфокусированными и маленькими, это приведет к более простому коду.
6.3. TDD
TDD означает “Испытание Driven развития”. Это практика программирования, которая просит нас писать любой код только в том случае, если автоматизированный тест . Следовательно, мы должны начать с разработки автоматизированных тестов . В Java существует несколько фреймворка для записи автоматизированных унитарных тестов, таких как JUnit и TestNG.
Преимущества такой практики огромны. Это приводит к программному обеспечению, которое всегда работает, как ожидалось. Как мы всегда начинаем с тестов, мы постепенно добавляем рабочий код небольшими кусками. Кроме того, мы добавляем код только в том случае, если новый или любой из старых тестов не удается. Это означает, что это приводит к повторному использования, а также.
7. Инструменты для помощи
Написание чистого кода – это не только принципы и практики, но и личная привычка. Мы склонны расти как лучшие разработчики, как мы учимся и адаптируемся. Тем не менее, для поддержания согласованности в большой команде, мы также на практике некоторые исполнения. Код обзоры всегда были отличным инструментом для поддержания согласованности и помочь разработчикам расти за счет конструктивной обратной связи.
Однако мы не обязательно должны проверять все эти принципы и передовой опыт вручную во время проверки кода. Фредди Гиме с Java OffHeap говорит о значении автоматизации некоторых проверок качества, чтобы в конечном итоге с определенным порогом с качеством кода все время.
Есть несколько инструментов, доступных в экосистеме Java , которые принимают по крайней мере некоторые из этих обязанностей от рецензентов кода. Давайте посмотрим, что некоторые из этих инструментов:
- Форматировщики кода: Большинство популярных редакторов Java-кода, включая Eclipse и IntelliJ, позволяют автоматически форматировать код. Мы можем использовать правила форматирования по умолчанию, настроить их или заменить их пользовательскими правилами форматирования. Это заботится о многих структурных конвенций кода.
- Инструменты статического анализа: Есть несколько инструментов статического анализа кода для Java, в том числе СонарКубе , Чекстайл , PMD и SpotBugs . Они имеют богатый набор правил, которые могут быть использованы как есть или настроены для конкретного проекта. Они отлично подхитовят в обнаружении большого количеством запахов кода, как нарушения конвенций именования и утечки ресурсов.
8. Заключение
В этом учебнике мы прошли через важность чистых принципов и характеристик кодирования, которые демонстрируют чистый код. Мы видели, как принять некоторые из этих принципов на практике, которые развиваются на Java. Мы также обсудили другие лучшие практики, которые помогают поддерживать код читаемым и поддерживаться с течением времени. Наконец, мы обсудили некоторые из имеющихся инструментов, чтобы помочь нам в этом начинании.
Подводя итог, важно отметить, что все эти принципы и практики существуют, чтобы сделать наш код чище. Это более субъективный термин и, следовательно, должны быть оценены контекстуально.
Хотя существует множество наборов правил, доступных для принятия, мы должны осознавать нашу зрелость, культуру и требования. Возможно, нам придется настроить или, если уж на то пошло, разработать новый набор правил в целом. Но, как бы то ни было, важно оставаться последовательным во всей организации, чтобы пожинать плоды.