Соглашение об именах параметров универсального типа для Java (с несколькими символами)?

125

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

Что-то вроде....

Map<Key,Value>

Вместо этого...

Map<K,V>

Но когда дело доходит до методов, параметры типа выглядят как java-классы, что тоже сбивает с толку.

public void put(Key key, Value value)

Похоже, что Key и Value - это классы. Я нашел или придумал некоторые обозначения, но ничего похожего на соглашение от Sun или общий передовой опыт.

Альтернативы я угадал или нашел ...

Map<KEY,VALUE>
Map<TKey,TValue>
chaper29
источник
9
Почему вы хотите создать новую конвенцию?
Амир Афгани
13
@AmirAfghani Из вопроса: сделать код более читабельным.
SantiBailors
Технически, разные оттенки дженериков в среде IDE должны служить достаточно хорошим индикатором
Судикс

Ответы:

182

Oracle рекомендует следующее в Руководстве по Java> Generics> Generic Types :

Соглашения об именах параметров типа

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

Наиболее часто используемые имена параметров типа:

  • E - Element (широко используется Java Collections Framework)
  • K - ключ
  • N - Число
  • T - Тип
  • V - значение
  • S, U, V и др. - 2-й, 3-й, 4-й типы

Вы увидите, что эти имена используются в Java SE API и в остальной части этого урока.

Я бы придерживался его, чтобы избежать путаницы среди разработчиков и возможных сопровождающих.

BalusC
источник
14
Новая структура потока также использует Rдля результата и Aдля аккумулятора.
vandale 09
32
Блек, однобуквенное именование. Я следую этому соглашению, потому что соглашение имеет большее значение, чем описательные имена, но, к сожалению, это лучшее, что они могли придумать.
warbaker
4
@warbaker: я считаю, что это хороший способ отличить параметризованные типы от реальных классов. Как иначе вы могли бы сказать, является ли, например, Elementin List<Element>параметризованным типом или классом?
BalusC
1
Не похоже, что BiFunction<T, U, R>это следует этому соглашению. Если бы это было так, то было бы BiFunction<T, S, R>.
michaelsnowden
4
Зачем беспокоиться об отличии параметризованных типов от реальных классов? Они являются классами. Несмотря ни на что, вам нужно прокрутить где-нибудь в файле, чтобы узнать, как они определены. И это будет либо импортный, либо параметризованный тип.
Vectorjohn
47

Append Type

Хорошее обсуждение можно найти в комментариях на странице DZone, Соглашения об именах для параметризованных типов .

См. Комментарий Эрвина Мюллера. Его предложение имеет для меня совершенно очевидный смысл: добавить словоType .

Назовите яблоко яблоком, машину машиной. Рассматриваемое имя - это имя типа данных, верно? (В ООП класс по существу определяет новый тип данных.) Назовите его «Тип».

Пример Мюллера, взятый из исходной статьи:

public interface ResourceAccessor < ResourceType , ArgumentType , ResultType > {
    public ResultType run ( ResourceType resource , ArgumentType argument );
}

Append T

Повторяющийся вопрос дает ответ Энди Томаса. Обратите внимание на отрывок из руководства по стилю Google, в котором предлагается, чтобы имя многосимвольного типа заканчивалось одной заглавной буквой T.

Василий Бурк
источник
3
Мне нравится этот ответ. Добавление «Типа» настолько ясно и позволяет вам иметь описательные имена. Меня тошнит от людей, говорящих «делай это, потому что это условность», без всякого другого оправдания. Если это плохая конвенция, возможно, нам нужна новая.
Дрю
16

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

Без этого соглашения было бы трудно отличить переменную типа от имени обычного класса или интерфейса.

Я думаю, что с современными IDE эта причина больше не действует, например. IntelliJ Idea показывает параметры универсального типа разными цветами, чем обычные классы.

Код с универсальным типом, как показано в IntelliJ Idea 2016.1 Код с универсальным типом, как показано в IntelliJ Idea 2016.1

Из-за этого различия я использую более длинные описательные имена для своих универсальных типов с тем же соглашением, что и обычные типы. Я избегаю добавления префиксов и суффиксов, таких как T или Type, поскольку считаю их ненужным шумом и больше не нужным для визуального различения общих типов.

Примечание. Поскольку я не являюсь пользователем Eclipse или Netbeans, я не знаю, предлагают ли они аналогичную функцию.

Войтех Ружичка
источник
Я бы не стал основывать соглашения об именах на основе предполагаемых возможностей инструментов, которые будут иметь каждый человек, когда-либо читавший / изменяющий тот же файл. Мне лично нравится использовать текстовый редактор для написания кода (Sublime Text), который не является IDE. Текстовые редакторы в настоящее время обычно имеют синтаксическую окраску, но не обладают глубоким пониманием базовой структуры кода, которое, как мне кажется, потребуется для правильной окраски имен переменных типов. И основывать этот аргумент на цвете по своей сути исключительно для людей с плохим цветовым зрением (я являюсь частью 8% мужчин с красно-зеленой дальтонизмом)
joonas.fi
1
Хороший аргумент в отношении людей с плохим цветовым зрением. Относительно отказа от использования IDE - если люди предпочитают использовать простые текстовые редакторы, это нормально, но они добровольно жертвуют функциями, которые IDE предлагают им, в пользу более легкого инструмента. Это может быть только одна из тех функций, которых не хватает. В конце концов, если вместо одной буквы используется описательное имя, вы сможете определить значение на основе имени без IDE и без цветовой кодировки. Цветовое кодирование делает это быстрее.
Войтех Ружичка
16

Да, вы можете использовать многосимвольные имена для переменных типа, если они четко отличаются от имен классов.

Это отличается от соглашения, предложенного Sun с введением дженериков в 2004 году. Однако:

  • Существует более одного соглашения.
  • Многосимвольные имена соответствуют другим стилям Java, таким как стиль Google для Java. .
  • Читаемые имена (сюрприз!) Более читабельны.

читабельность

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

Читаемость хорошая.

Для сравнения:

    public final class EventProducer<L extends IEventListener<E>,E> 
            implements IEventProducer<L,E> {

чтобы:

    public final class EventProducer<LISTENER extends IEventListener<EVENT>,EVENT> 
           implements IEventProducer<LISTENER, EVENT> {

или, согласно многосимвольному соглашению Google:

    public final class EventProducer<ListenerT extends IEventListener<EventT>,EventT> 
           implements IEventProducer<ListenerT, EventT> {

    public final class EventProducer<ListenerT extends IEventListener<EventT>,EventT> 
           implements IEventProducer<ListenerT, EventT> {

Стиль Google

Руководство по стилю Google Java допускает как однобуквенные, так и многосимвольные имена класса, заканчивающиеся на T.

5.2.8 Имена переменных типа

Каждой переменной типа присвоено имя в одном из двух стилей:

  • Одна буква, необязательно с последующим одной цифрой (например E, T, X, T2)

  • Имя в форме , используемой для классов (смотрите Раздел 5.2.2, имена классов ), а затем буквы Т (примеры: RequestT, FooBarT).

вопросы

«Без этого соглашения было бы трудно отличить переменную типа от обычного класса или имени интерфейса». - из руководств Oracle «Универсальные типы»

Односимвольные имена - не единственный способ отличить параметры типа от имен классов, как мы видели выше.

Почему бы просто не задокументировать значение параметра типа в JavaDoc?

Верно, что @paramэлементы JavaDoc могут содержать более подробное описание. Но также верно и то, что JavaDocs не обязательно видимы. (Например, в Eclipse есть помощник по содержанию, который показывает имена параметров типа.)

Имена параметров многосимвольного типа не соответствуют соглашению Oracle!

Многие оригинальные соглашения Sun почти повсеместно соблюдаются в программировании на Java.

Однако этого конкретного соглашения нет.

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

Энди Томас
источник
15

Вы можете использовать javadoc, чтобы хотя бы дать подсказку пользователям вашего универсального класса. Мне все еще это не нравится (я согласен с @ chaper29), но документы помогают.

например,

/**
 * 
 * @param <R> - row
 * @param <C> - column
 * @param <E> - cell element
 */
public class GenericTable<R, C, E> {

}

Еще я, как известно, использовал свою IDE для рефакторинга класса, нарушая соглашение. Затем поработайте над кодом и вернитесь к одинарным буквам. В любом случае мне будет легче, если используется много параметров типа.

Том Карчрей
источник
1
Я бы сказал, что комментарии Javadoc для параметров типа обычно необходимы.
Migu