Как назвать файл с константами
Всем привет. продолжаем изучать платформу 1С: Предприятие 8.3. Это уже второй урок, в котором мы начнем изучать основные объекты платформы для возможности разработки собственного приложения. Первый объект - это константа.
Приступим к изучению!
Часть 1. Запуск созданной информационной базы ( Урок 1 )
Запустим ярлык на рабочем столе, откроется уже знакомое окно, в котором есть два режима: режим разработчика и режим пользователя. Так как в прошлом уроке мы мы создали информационную базу, нам ее еще раз создавать ненужно. Выделим нашу информационную базу "Автоматизация предприятия" и нажмем на кнопку "Конфигуратор". По нажатию на эту кнопку происходит переход в режим разработчика.
Здесь нужно понять лишь один смысл! Если мы хотим разработать что-то свое, то это только режим разработчика. Если мы хотим работать в существующей программе, то это режим пользователя. Платформа позволяет работать одному человеку сразу в двух режимах (сначала что-то разработал, потом заходишь и проверяешь).Учебная версия - она ограничена по функционалу и дает возможность работать только одному человеку. А если лицензия - то их может доходить и до 300 (все зависит от вида лицензии).
Нажимаем кнопку "Конфигуратор" (Рисунок 1).
Произошел переход в режим разработчика (Рисунок 2).
На рисунке 2 показана иконка, на которую нужно нажать и у вас откроется дерево конфигурации (Рисунок 3).
Дерево конфигурации - это дерево, которое имеет ветви, а каждая ветвь в свою очередь имеет какие-то отростки - объекты. Объекты - это константы, справочники, документы и так далее. Более подробно можно почитать нажав сюда.
Все, что сейчас находится в режиме разработчика - это инструменты, с которыми будет работать программист для создания своей программы, но это ничего не видно в режиме пользователя.
Как только разработчик создает справочник или константу, она сразу же отображается в режиме пользователя.
В прошлом уроке мы пробовали создавать справочник, но перед этим заходили в режим пользователя, чтобы убедиться в том, что там ничего нет. Добавили справочник и только после этого у пользователя появилась возможность сразу автоматизировать свою деятельность.
Ничего не создавая, перейдем в режим пользователя и еще раз убедимся в том, что там ничего нет. Для этого выполним команду: "Сервис-1С:Предприятие" (Рисунок 4).
Откроется знакомое окно и оно действительно пустое (Рисунок 5).
На рисунке 5 отображается пользовательский режим, а сверху написано имя вашей программы и называется она "Конфигурация". Давайте изменим его и назовем "Автоматизация предприятия". Закроем режим "1С: Предприятие" на крестик в верхнем правом углу и вернемся в режим разработчика.
Выделим в дереве конфигурации корень этого дерева - слово Конфигурация, правой кнопкой мыши вызовем контекстное меню (или дважды щелкнем по нему правой кнопкой мыши) и выберем пункт "Свойства" (Рисунок 6).
Откроется палитра свойств (рисунок 7)
Палитра свойств - это окно, в котором отображаются все свойства, доступные для данного объекта. В данном случае, это свойства всего дерева конфигурации.
В открывшейся палитре свойств нам сейчас важны два свойства, Имя и Синоним.
Имя - это идентификатор, который нужен для разработчика и виден от только разработчику. Он нужен программисту для того, чтобы он мог к нему с помощью кода обратиться и где-то использовать.
Синоним - это имя, которое будет отображаться в пользовательском режиме и будет видно пользователю. То есть это то свойство, которое необходимо для пользователя.
Имя и синоним могут быть одинаковыми. Правила задания свойства "Имя":
1. Должно начинаться с буквы
2. Не может содержать пробелов и других специальных символов кроме подчеркивания "_"
3. Пишется слитно, но каждое слово с большой буквы - "АвтоматизацияПредприятия". Этот способ называется - верблюжий. В этом случае платформа понимает, что ей необходимо отделить каждое слово друг от друга (Рисунок 8).
Часть 2. Изменим имя конфигурации (программы)
Изменим имя "Конфигурация" на "АвтоматизацияПредприятия" и нажмем "Tab". В этом случае (Рисунок 8) синоним автоматически заполнится и разделится на два слова (но можно и просто перенести курсор в поле синоним), а свойство Имя останется также слитно - так и должно быть.
Таким образом мы изменили нашу программу (она называется конфигурация или программное решение - это термины 1С). Посмотрите на рисунок 8, в дереве объектов изменилось название. Теперь необходимо обновить программу, внести изменения и проверить все в пользовательском режиме. Нажмем клавишу F7 или значок на панели инструментов (Рисунок 9)
После того, как нажали клавишу или на этот значок, значок обновления должен стать серым и недоступным - это значит, что пока нет никаких изменений в вашей программе.
Перейдем теперь в режим пользователя и проверим изменения. Для этого необходимо выполнить команду "сервис-1С6Предприятие". Откроется знакомое окно, в котором будет название нашей программы (рисунок 10).
Сейчас вы уже сделали первых два шага по разработке своей конфигурации и это уже совсем не плохо!
Часть 2. Создание константы
Теперь необходимо как-то дальше разработать программу, чтобы она подходила для вашего предприятия.
Что такое константа? Константа - это объект дерева конфигурации, который предназначен для хранения постоянной величины или величины, которая меняется очень редко.
Константа я языках программирования - это то, что никогда не изменяется. Тем это и отличается в платформе. В платформе 1С это величина, которая изменяется крайне редко.
Вся платформа 1С создана так, что ее смысл понятен в русском языке. Константа в жизни каждого человека, это, например, его имя. Оно вроде является постоянной величиной, но его можно изменить. Или, это фамилия, инн, адрес и так далее. все это константы в понимании 1С.
Константа нужна для хранения "постоянной" величины. В нашем случае константами будут являться: 1. ИНН организации, имя директора магазина, адрес магазина и так далее - все это константы.
Перейдем в режим разработчика, выделим константу и правой кнопкой мыши добавим новую константу (или это можно сделать иначе. Выделить константы и нажать на плюсик в верхней панели дерева объектов).
При компиляции класса Java создается файл класса с тем же именем. Однако, в случае вложенных классов или вложенных интерфейсов, он создает файл класса с именем, сочетающий внутренние и внешние имена классов, включая знак доллара.
В этой статье мы увидим все эти сценарии.
2. Подробная информация
В Java мы можем написать класс в классе. Класс, написанный внутри, называется вложенным классом, а класс, в который находится вложенный класс, называется внешним классом. Область вложенного класса ограничена областью его прилагаемого класса.
Аналогичным образом, мы можем объявить интерфейс в другом интерфейсе или классе. Такой интерфейс называется вложенным интерфейсом.
Мы можем использовать вложенные классы и интерфейсы для логически групповых сущностей, которые используются только в одном месте. Это не только делает наш код более читаемым и управляемым, но и увеличивает инкапсуляцию.
В следующих разделах мы подробно обсудим каждый из них. Мы также посмотрим на enums.
3. Вложенные классы
Вложенный класс является классом, который объявляется внутри другого класса или интерфейса. Каждый раз, когда нам нужен отдельный класс, но все же мы хотим, чтобы класс вел себя как часть другого класса, вложенный класс является лучшим способом его достижения.
Когда мы компилировать файл Java, он создает .class файл для класса ограждения и отдельные файлы классов для всех вложенных классов. Сгенерированный файл класса для класса ограждения будет иметь то же имя, что и класс Java.
Прежде всего, давайте создадим простой класс Java:
3.1. Статические вложенные классы
Как следует из названия, вложенные классы, которые объявлены статические называются статическими вложенными классами. В Java разрешается использовать только вложенные статический.
Статические вложенные классы могут иметь как статические, так и нестатическое поля и методы. Они привязаны к внешнему классу, а не к определенному экземпляру. Следовательно, нам не нужен экземпляр внешнего класса, чтобы получить к ним доступ.
Давайте объявим статический вложенный класс в нашем Внешние класс:
Когда мы компилировать наши Внешние класс , компилятор создает два файла класса, один для Внешние и еще один для СтатическаяНеупойс :
3.2. Нестатическое гнездование классов
Внешний класс может иметь только общедоступный или по умолчанию доступ, в то время как внутренний класс может быть частным, общедоступный, защищенный или с доступом по умолчанию. Тем не менее, они не могут содержать статических элементов. Кроме того, нам нужно создать экземпляр внешнего класса, чтобы получить доступ к внутреннему классу.
Давайте добавим еще один вложенный класс в наш Внешние класс:
Он генерирует еще один файл класса:
3.3. Местные классы
Локальные классы, также называемые внутренними классами, определяются в блоке – группе утверждений между сбалансированными скобками. Например, они могут быть в методе тела, для петля, или если статья. Область действия локального класса ограничена внутри блока так же, как и локальные переменные. Локальные классы при составлении отображаются как знак доллара с автоматически генерируемым номером.
Файл класса, генерируемый для локального класса, использует конвенцию именования — OuterClassName$1LocalClassName.class
Давайте объявим локальный класс в методе:
Компилятор создает отдельный класс файла для нашей Местные класс:
Аналогичным образом, мы можем объявить местный класс в если статья:
Несмотря на то, что мы создаем другой локальный класс с тем же названием, компилятор не жалуется. Он создает еще один класс файла и называет его с числом увеличилось:
3.4. Анонимные внутренние классы
Как следует из названия, анонимные классы являются внутренними классами без имени. Компилятор использует автоматически генерируемый номер после знака доллара, чтобы назвать файл класса.
Мы должны объявить и мгновенно анонимных классов в одном выражении в то же время. Они обычно расширяют существующий класс или реализуют интерфейс.
Рассмотрим быстрый пример:
Здесь мы создали анонимный класс, расширяя Внешние класс, и компилятор добавил еще один файл класса:
Аналогичным образом, мы можем реализовать интерфейс с анонимным классом.
Здесь мы создаем интерфейс:
Теперь давайте создадим анонимный класс:
Рассмотрим пересмотренный список файлов классов:
Как мы видим, файл класса генерируется для интерфейса HelloWorld и еще один для анонимного класса с именем Внешни$ $2 .
3.5. Внутренний класс в интерфейсе
Мы видели класс внутри другого класса, далее, мы можем объявить класс в интерфейсе. Если функциональность класса тесно связана с функциональностью интерфейса, мы можем объявить ее внутри интерфейса. Мы можем пойти на этот внутренний класс, когда мы хотим написать реализацию по умолчанию для методов интерфейса.
Давайте объявим внутренний класс внутри нашего HelloWorld интерфейс:
И компилятор генерирует еще один файл класса:
4. Вложенные интерфейсы
Вложенные интерфейсы, также известные как внутренние интерфейсы, объявлены внутри класса или другого интерфейса. Основная цель использования вложенных интерфейсов заключается в разрешении пространства имен путем группировки связанных интерфейсов.
Давайте посмотрим, как создать вложенные интерфейсы.
4.1. Интерфейс внутри интерфейса
Интерфейс, заявленный внутри интерфейса, неявно общедоступен.
Давайте объявим наш интерфейс внутри HelloWorld интерфейс:
Это позволит создать новый класс файла под названием HelloWorld$HelloSomeone для вложенного интерфейса.
4.2. Интерфейс внутри класса
Интерфейсы, заявленные внутри класса, могут принимать любой модификатор доступа.
Давайте объявим интерфейс внутри нашей Внешние класс:
Он будет генерировать новый файл класса с именем: Внешнийкласс$СтатическийКласс
5. Энумы
enum был введен в Java 5. Это тип данных, который содержит фиксированный набор констант, и эти константы являются примерами этого enum .
enum декларация определяет класс называется e num типа (также известного как перечисленный тип данных). Мы можем добавить много вещей к enum как конструктор, методы, переменные, и то, что называется постоянным конкретным телом класса.
Когда мы создаем enum , мы создаем новый класс, и мы неявно расширения Энум класса. Энум не может унаследовать любой другой класс или не может быть продлен. Тем не менее, он может реализовать интерфейс.
Мы можем объявить enum как отдельный класс, в его собственном файле источника или другой член класса. Давайте посмотрим все способы создания enum .
5.1. Энум как класс
Во-первых, давайте создадим простую enum :
Когда он будет составлен, компилятор создаст файл класса с именем Уровень для нашего enum.
5.2. Энум в классе
Теперь давайте объявим вложенный enum в нашем Внешние класс:
Компилятор создаст отдельный классный файл под названием Внешни$ цвет для нашего вложенного enum.
5.3. Enum в интерфейсе
Аналогичным образом, мы можем объявить enum в интерфейсе:
Когда HelloWorld интерфейс компилятора добавит еще один классный файл под названием HelloWorld$Прямой.
5.4. Энум в пределах enum
Мы можем объявить enum внутри другого enum :
Наконец, давайте посмотрим на генерируемые файлы класса:
Компилятор создает отдельный файл класса для каждого из enum Типы.
6. Заключение
В этой статье мы увидели различные конвенции именования, используемые для файлов класса Java. Мы добавили классы, интерфейсы и enums внутри одного файла Java и наблюдали, как компилятор создает отдельный файл класса для каждого из них.
Есть лучший способ это сделать? Неловко объявлять константу в объекте экспорта.
Вы можете явно экспортировать его в глобальную область с помощью global.FOO = 5 . Тогда вам просто нужно запросить файл, и даже не сохранять возвращаемое значение.
Но на самом деле, вы не должны этого делать. Правильно хранить вещи в инкапсуляции. У вас уже есть правильная идея, поэтому продолжайте делать то, что делаете.
На мой взгляд, использование Object.freeze позволяет использовать СУХОЙ и более декларативный стиль. Мой предпочтительный шаблон:
./lib/constants.js
./lib/some-module.js
Предупреждение об устаревшей производительности
Следующая проблема была исправлена в v8 в январе 2014 года и больше не актуальна для большинства разработчиков:
Из предыдущего опыта проекта, это хороший способ:
В main.js (или app.js и т. Д.) Используйте его, как показано ниже:
В качестве альтернативы вы можете сгруппировать ваши «постоянные» значения в локальный объект и экспортировать функцию, которая возвращает поверхностный клон этого объекта.
Тогда не имеет значения, если кто-то переназначит FOO, потому что это повлияет только на их локальную копию.
Я сделал это, экспортировав замороженный объект с анонимными функциями получения, а не с самими константами. Это снижает риск появления неприятных ошибок из-за простой опечатки с именем const, так как в случае опечатки будет выдана ошибка времени выполнения. Вот полный пример, который также использует символы ES6 для констант, обеспечивая уникальность, и функции стрелок ES6. Был бы признателен за обратную связь, если что-либо в этом подходе кажется проблематичным.
Я не думаю, что это хорошая практика для вторжения в пространство GLOBAL из модулей, но в сценариях, где это может быть строго необходимо для его реализации:
Это следует учитывать влияние этого ресурса. Без правильного именования этих констант риск ЗАВЕРШЕНИЯ уже определенных глобальных переменных является чем-то реальным.
Я думаю, что const решает проблему для большинства людей, которые ищут этот ответ. Если вам действительно нужна неизменная константа, посмотрите на другие ответы. Чтобы все было организовано, я сохраняю все константы в папке, а затем требую всю папку.
Файл src / main.js
SRC / consts_folder / index.js
Ps . здесь deal и note будут первым уровнем main.js
Папка src / contacts / node.js
Ps . obj будет вторым уровнем в main.js
SRC / consts_folder / deal.js
Ps . str будет вторым уровнем в main.js
Окончательный результат в файле main.js:
Я рекомендую сделать это с помощью веб-пакета (предполагается, что вы используете веб-пакет).
Определить константы так же просто, как установить файл конфигурации webpack:
Таким образом, вы определяете их вне вашего источника, и они будут доступны во всех ваших файлах.
Я нашел решение, предложенное Домиником, лучшим, но в нем все еще отсутствует одна особенность декларации «const». Когда вы объявляете константу в JS с ключевым словом «const», существование константы проверяется во время разбора, а не во время выполнения. Поэтому, если вы ошиблись в названии константы где-то позже в своем коде, вы получите ошибку при попытке запустить программу node.js. Который намного лучше проверяет орфографию.
Если вы определили константу с помощью функции define (), как предложил Доминик, вы не получите ошибку, если вы ошиблись в написании константы, а значение константы с ошибкой будет неопределенным (что может привести к головной боли при отладке).
Но я думаю, это лучшее, что мы можем получить.
Кроме того, вот что-то вроде улучшения функции Доминика в constans.js:
Таким образом, вы можете использовать функцию define () в других модулях, и она позволяет вам определять константы как внутри модуля constants.js, так и констант внутри вашего модуля, из которого вы вызвали функцию. Объявление констант модуля может быть сделано двумя способами (в script.js).
Кроме того, если вы хотите, чтобы функция define () вызывалась только из модуля констант (не для того, чтобы раздувать глобальный объект), вы определяете ее следующим образом в constants.js:
И используйте это так в script.js:
import и export (вероятно, что-то вроде babel с 2018 года, чтобы использовать импорт)
экспорт в foo.js
Технически, const не является частью спецификации ECMAScript. Кроме того, используя шаблон «CommonJS Module», который вы заметили, вы можете изменить значение этой «константы», поскольку теперь это просто свойство объекта. (не уверен, что это приведет к каскадным изменениям в других скриптах, для которых требуется тот же модуль, но это возможно)
Чтобы получить реальную константу, которой вы также можете поделиться, проверьте >, Object.defineProperty и Object.defineProperties . Если вы установите writable: false , то значение в вашей «константе» не может быть изменено. :)
Это немного многословно (но даже это можно изменить с помощью небольшого JS), но вам нужно будет сделать это только один раз для вашего модуля констант. Используя эти методы, любой атрибут, который вы пропускаете, по умолчанию равен false . (в отличие от определения свойств посредством присваивания, в котором все атрибуты по умолчанию имеют значение true )
Итак, гипотетически, вы можете просто установить value и enumerable , опуская writable и configurable , так как они по умолчанию будут false , я только что включил их для ясности.
Обновление . Я создал новый модуль (константы узла) с вспомогательными функциями для этого самого варианта использования.
Имя файла с исходным кодом состоит из регистро-чувствительного имени класса верхнего уровня, который располагается в этом файле, плюс .java расширение. Класс верхнего уровня в файле может быть только один.
Файлы с исходным кодом хранятся в кодировке UTF-8.
Символы пустого места
Кроме символов перевода строки, только ASCII-пробел (0x20) встречается в файлах. Это означает:
- Все остальные символы пустого места эскейпятся (escaped).
- Табы не используются для отступов.
Для любого символа, который имеет специальную escape-последовательность (b, \t, \n, \f, \r, ", ' и \), эта последовательность используется вместо соответствующего octal (например \012) или Unicode-символа (например \u000a).
Для остальных не-ASCII символов, используется или сам Unicode-символ (например ∞) или соответствующий Unicode escape-символ (например \u221e). Выбор символа зависит только о того, насколько легко код с ним читать и понимать, хотя Unicode escape-символы вне строковых литералов и комментариев вставлять не рекомендуется.
Совет: в случае использования Unicode escape-символа, и иногда даже когда используется сам Unicode символ, поясняющие комментарии могут быть полезны.
Пример | Комментарии |
---|---|
String unitAbbrev = "μs"; | Лучший вариант: все ясно даже без комментария |
String unitAbbrev = "\u03bcs"; // "μs" | Разрешается, но нет причины так делать |
String unitAbbrev = "\u03bcs"; // Greek letter mu, "s" | Разрешается, но странно выглядит и неустойчиво к ошибкам |
String unitAbbrev = "\u03bcs"; | Плохо: читатель не поймет, что это такое |
return '\ufeff' + content; // byte order mark | Хорошо: используется escape-символ для непечатных символов, и есть коммент |
Совет: не делайте ваш код менее читаемым просто из боязни, что какая-либо программа не сможет обработать не-ASCII символы верно. Если такое случается, значит программа работает неправильно и должна быть починена.
Файл с исходным кодом состоит из:
- Лицензия или информация о копирайте, если есть
- Имя пакета
- Импорты классов
- Только один класс верхнего уровня
Секции разделяются одной пустой линией.
Имя пакета не разделяется переносом строки. Заданная нами длина строки не распространяется на строку с именем пакета.
Использование wildcard и static импортов не рекомендуется. Исключение: если ситуация оправдана, и все испортируемые методы и константы близки по смыслу к классу в данном файле.
Импорт не разделяется переносом строки. Заданная нами длина строки не распространяется на строку с импортом класса.
Нет специальных правил на порядок импортов. Придерживаемся стиля, заданного по-умолчанию в используемой всеми IDE.
Каждый класс верхнего уровня находится в отдельном файле с его именем.
Порядок расположения членов класса
Члены классы располагаются в таком порядке:
- static-поля
- поля
- конструкторы
- static-методы
- перекрытые (overriden) методы
- методы
- get/set методы
- внутренние классы
Не разрываем последовательность перегруженных методов
Если у класса есть несколько конструкторов или методов с одним и тем же именем, они располагаются друг за другом, без включения других полей/методов
Ставим скобки, даже если это необязательно
Скобки используются с if , else , for , do и while , даже если их тело пустое или содержит только 1 оператор.
Непустые блоки: стиль K & R
Скобки ставятся в соответствии со стилем Кернигана и Ричи (Египетские скобки) для непустых блоков:
- Нет перевода строки до открывающей скобки
- Перевод строки после открывающей скобки
- Перевод строки до закрывающей скобки
- Перевод строки после закрывающей скобки, если эта скобка заканчивает оператор, тело метода, конструктор или класс. Например, нет перевода строки после закрывающей скобки, если после неё стоит else или точка с запятой.
Исключения делаются для Enum-классов.
Пустые блоки не укорачиваем
Ставим перевод строки и комментарий, даже если тело блока пустое:
Отступы слева для блоков
Каждый раз, когда мы открываем новый блок, отступ увеличивается на 2 пробела. Когда блок заканчивается, отступ возвращается до прежнего значения. Отступ применяется и для комментариев в блоке.
Одно выражение на строку
Каждое выражение или оператор заканчивается переводом строки.
Длина строки в коде имеет лимит в 120 символов. Кроме исключений, любая строка больше лимита должна быть разбита на 2 строки, как описано в разделе Перенос строки.
- Строки, для которых невозможно соблюсти лимит (например, длинный URL в Javadoc)
- Имя пакета и импорты (см. Имена пакетов и Импорты классов)
- Команды, которые можно скопировать в командную строку для выполнения (shell)
Нет точной формулы или алгоритма для перевода строк в каждой ситуации. Часто есть несколько способов. Основная цель - сделать код более понятным и ясным, а необязательно укладывающимся в минимальное число строк. Совет: хотя одна из целей использования переноса строк - соблюсти лимит длины строки в коде, часто автор может перенести код на другую строку, даже если он укладывался в лимит. Совет: выделение метода или локальной переменной может решить проблему без необходимости переносить строку.
Отступы для перенесенных строк - 8 пробелов
При переносе строк, каждая перенесенная строка после самой первой отступает слева на 8 пробелов от начальной строки. В общем случае, отступ для 2 перенесенных строк будет одинаковым только если начинаются с синтаксически параллельных конструкций.
Вертикальное пустое место
Одна пустая строка стоит:
- Между последовательными членами класса: поля, конструкторы, методы, вложенные классы, static-инициализация, инициализация экземпляров классов.
- Исключение: пустая строка между 2 полями опциональна (если нет другого кода между ними). Такие пустые строки могут отделять логические группы полей.
- Исключение: пустые строки между Enum-константами описаны в разделе про Enum-классы.
Несколько пустых строк подряд разрешается, но не обязательно.
Горизонтальное пустое место
Одиночный ASCII-пробел встречается в следующих местах (помимо требования синтаксиса языка, литералов, комментов и javadoc):
- Отделяет любое зарезервированное слово, такое как catch, for или if, от открывающей круглой скобки, которая идет далее в этой строке
- Отделяет любое зарезервированное слово, такое как else или catch, от закрывающей фигурной скобки, которая предшествует этому слову в этой строке
- Перед любой открывающей фигурной скобкой ( <), кроме:
- @SomeAnnotation() (нет пустого места)
- Амперсанд в пересечении типов: <T extends Foo & Bar>
- Вертикальная черта (pipe) для блока catch, который обрабатывает несколько исключений: catch (FooException | BarException e)
- Двоеточие (:) в for ("foreach")
- Стрелка в лямбда-выражении: (String str) -> str.length()
- Два двоеточия (::) для ссылки на метод, в записи вида Object::toString
- Для точки-разделителя при вызове метода, в записи вида object.toString()
Правила относятся к пробелам внутри строки, а не отступам (оговариваются в другом разделе).
Горизонтальное выравнивание не используется
Горизонтальное выравнивание - практика добавления разного числа пробелов в коде с целью того, чтобы некоторые конструкции располагались точно под другими конструкциями на вышестоящей строке. Мы не используем горизонтальное выравнивание, и рекомендуется убирать его при рефакторинге. Пример:
Выравнивание может улучшить читаемость, но создает проблемы для дальнейшей поддержки. Допустим, последующее изменение затрагивает всего 1 строку. Часто такое изменение сбивает выравнивание, что выглядит уже не так хорошо. Но чаще разработчик стремится поддержать порядок выравнивания и меняет оступы в других строках, инициируя каскадную серию форматирований. Это однострочное изменение теперь имеет "радиус поражения". Это бесполезная работа, также это ухудшает читаемость истории версий, замедляет ревьюеров и затрудняет разрешение merge-конфликтов.
После каждой запятой после определения Enum-константы нужен перевод строки. Дополнительно допускается пустая строка после этого. Пример:
Enum-классы в остальном подчиняются общим правилам оформления классов.
В каждой строке определяется только одна переменная
Каждое определение (поле или локальная переменная) состоит только из одной переменной: определения вида int a, b; не используются.
Переменные определяются по мере надобности
Локальные переменные не обязательно должны определятся в начале блока или метода. Вместо этого, он определяются как можно ближе к месту их первого использования, чтобы уменьшить область действия переменной. Локальные переменные как правило сразу инициализируются.
Квадратные скобки ставятся рядом с типом, а не самой переменной: String[] args, но не String args[].
Внутри скобок в switch-блоке располагаются одна или несколько групп операторов. Каждая группа содержит одну или несколько меток (например FOO: или default:), за которой следуют операторы.
Как и с другими блоками, оступ для содержимого составляет +2 пробела. После метки стоит перевод строки, и отступ снова увеличивается на +2, как в случае с открытием нового блока. Следующая метка находится на предыдущем уровне, как будто блок закрылся.
Провалы в следующие метки: не используются
Внутри switch-блока, группа операторов заканчивается break, continue, return или выбросом исключения. Провалы в следующие метки недопустимы - это сильно снижает читаемость, и сложно визуально выделить и отследить логику провала по меткам. Пример:
Исключения делается только для пустых меток (пример выше с case 1:). Для каждого switch должна быть default-метка, даже если она не содержит кода.
Аннотации, применяемые к классу, методу или конструктору ставятся сразу после блока документации, и находятся на отдельной строке (по одной аннотации на строке). Отступ слева после аннотации не увеличивается. Пример:
Нет специальных правил для форматирования аннтотаций на параметрах, локальных переменных, типах.
Блочные комментарии имеют тот же отступ слева, что и окружающий их код. Они могут быть записаны в стиле /* . */ или // . Для многострочных комментариев, последующие строки могут начинаться со * , которая выравнена со звездочкой на предыдущей строке. Примеры:
Комменты не должны быть заключены в прямоугольники из звездочек или других символов. Совет: когда пишете многострочные комментарии, используйте стиль /* . */ для того, чтобы автоматические форматтеры переносили строки когда нужно. Большинство форматтеров не могут сделать такое для //.
Модификаторы классов и методов ставятся в порядке, рекомендованном Java Language Specification:
public protected private abstract default static final transient volatile synchronized native strictfp
Числовые литералы типа long используют большую букву L, никогда не используется нижний регистр (чтобы избежать путаницы с цифрой 1). Например, надо писать 3000000000L вместо 3000000000l.
Правила для всех идентификаторов
Для идентификаторов используются только ASCII буквы и цифры, и в малом числе исключений, нижнее подчеркивание ( _ ). Поэтому каждое валидное имя идентификатора попадает под регулярное выражение \w+ . В нашем стиле кодирования специальные префиксы и суффиксы, такие как name_, mName, s_name и kName, не используются.
Имена пакетов пишутся в нижнем регистре, слова просто последовательно конкатенируются друг с другом (без нижних подчеркиваний). Например, com.example.deepspace, а не com.example.deepSpace или com.example.deep_space.
Имена классов пишутся в UpperCamelCase.
Имена классов - это обычно существительные или фразы с существительными. Например, Character или ImmutableList. Интерфейсы тоже могут называться существительными или фразами с существительными (например, List), но иногда могут быть прилагательными или фразами с прилагательными (например, Readable).
Нет специальных правил для именования аннотаций.
Тестовые классы начинаются с имени класса, который они тестируют, и заканчиваются на Test. Например, HashTest или HashIntegrationTest.
Имена методов пишутся в lowerCamelCase.
Имена методов - обычно глаголы или фразы с глаголами. Например, sendMessage или stop.
Нижние подчеркивания могут быть в тестовых методах JUnit для отделения логических компонентов имени. Типичный шаблон - test<MethodUnderTest>_<state> , например testPop_emptyStack. Нет Одного Правильного Способа для именования тестовых методов.
Имена констант используют CONSTANT_CASE: все буквы в верхнем регистре, слова отделяются нижним подчеркиванием. Но что есть константа?
Каждая константа является static final полем, но не все static final поля являются константами. Прежде чем именовать переменную константой, подумайте реально ли она является ей. Например, если видимое состояние экземпляра обьекта может измениться, это точно не константа. Просто мысли о том, что объект не будет меняться в процессе работы, не достаточно. Примеры:
Имена констант - обычно существительные или фразы с существительными.
Имена неконстантных полей
Не константы (static или нет) пишутся в lowerCamelCase. Эти имена - обычно существительные или фразы с существительными. Например, computedValues или index.
Имена параметров пишутся в lowerCamelCase. Односимвольных имен параметров в публичных методах следует избегать.
Имена локальных переменных
Имена локальных переменных пишутся в lowerCamelCase. Даже когда они final и immutable, локальные переменные не надо путать с константами, и именовать их как константы.
Имена переменных типов
Каждая переменная типа именуется одним из 2 способов:
- Одна большая буква, опционально с цифрой после (например E, T, X, T2).
- Имя, похожее на имя класса, с буквой T после (например: RequestT, FooBarT).
Определение Camel Case
Иногда есть несколько способов конвертировать английскую фразу в camel case, например для аббревиатур или необычных имен типа "IPv6" или "iOS". Чтобы имя было предсказуемо, предлагается такая схема.
- Берем имя или фразу
- Конвертируем её в набор ASCII символов и убираем все апострофы. Например, "Müller's algorithm" может стать "Muellers algorithm".
- Делим результат на слова, разбивая по пробелам или другим знакам препинания (обычно дефисы). Если одно из слов уже употребляется в camel case, разбиваем его (например, AdWords становится ad words). Слова типа "iOS" не попадают под это правило, потому что они на самом деле не camel case.
- Приводим все к нижнему регистру (включая аббревиатуры), затем приводим первую букву к верхнему регистру:
- каждого слова, если хотим получить upper camel case
- каждого слова, кроме первого, если хотим получить lower camel case
Примите во внимание, что регистр букв в оригинальных словах не принимается во внимание. Примеры:
Оригинальная фраза Правильно Неправильно "XML HTTP request" XmlHttpRequest XMLHTTPRequest "new customer ID" newCustomerId newCustomerID "inner stopwatch" innerStopwatch innerStopWatch "supports IPv6 on iOS?" supportsIpv6OnIos supportsIPv6OnIOS "YouTube importer" YouTubeImporter YoutubeImporter Примечание: некоторые слова имеют несколько написаний через дефис в английском языке, например оба "nonempty" и "non-empty" верны. Таким образом, имена методов checkNonempty и checkNonEmpty тоже оба верны.
@Override: всегда используется
Метод всегда помечается аннотацией @Override, если это верно с точки зрения языка. Это включает в себя:
- Метод класса, переопределяющий метод суперкласса
- Метод класса, реализующий метод интерфейса
- Метод интерфейса, переопределяющий метод суперинтерфейса
Исключение: @Override можно опустить, если метод родителя обьявлен как @Deprecated.
Перехватываемые исключения: не игнорируются
Кроме случая, описываемого ниже, очень редко является корректным ничего не делать в ответ на перехваченное исключение (типовые способы: логгировать его, если же обьявлено "невозможным", выбросить заново как AssertionError).
Когда реально ничего не надо делать в catch-блоке, причина указывается в поясняющем комментарии:
Исключение: в тестах, перехваченное исключение может игнорироваться без комментария, если имя переменной начинается с expected. Это часто встречается, когда надо убедиться, что тестируемый код бросает исключение нужного типа, поэтому комментарий излишен.
Статические члены класса: указываются через имя класса
Когда нужно указать или сослаться на статическое поле или метод класса, оно определяется с именем класса, а не с ссылкой на обьект или выражение, возвращающее объект типа этого класса.
Finalizers: не используются
Очень редко надо переопределять Object.finalize .
Совет: не делайте этого. Если позарез надо, сначала прочитайте и поймите Effective Java Item 7, "Avoid Finalizers", а после этого не делайте этого.
Читайте также: