Convention de dénomination des paramètres de type générique pour Java (avec plusieurs caractères)?

125

Dans certaines interfaces que j'ai écrites, j'aimerais nommer les paramètres de type générique avec plus d'un caractère pour rendre le code plus lisible.

Quelque chose comme....

Map<Key,Value>

Au lieu de cela...

Map<K,V>

Mais en ce qui concerne les méthodes, les paramètres de type ressemblent à des classes java, ce qui est également déroutant.

public void put(Key key, Value value)

Cela semble que la clé et la valeur sont des classes. J'ai trouvé ou pensé à quelques notations, mais rien de tel qu'une convention de Sun ou une meilleure pratique générale.

Alternatives que j'ai devinées ou trouvées ...

Map<KEY,VALUE>
Map<TKey,TValue>
chaper29
la source
9
Pourquoi voulez-vous créer une nouvelle convention?
Amir Afghani
13
@AmirAfghani De la question: rendre le code plus lisible.
SantiBailors
Techniquement, la teinte différente des génériques dans l'EDI devrait servir d'indicateur assez bon
Sudix

Réponses:

182

Oracle recommande ce qui suit dans Tutoriels Java> Génériques> Types génériques :

Conventions de dénomination des paramètres de type

Par convention, les noms des paramètres de type sont des lettres majuscules uniques. Cela contraste fortement avec la dénomination des variables conventions de que vous connaissez déjà, et pour une bonne raison: sans cette convention, il serait difficile de faire la différence entre une variable de type et un nom de classe ou d'interface ordinaire.

Les noms de paramètres de type les plus couramment utilisés sont:

  • E - Element (largement utilisé par Java Collections Framework)
  • K - Clé
  • N - Nombre
  • T - Type
  • V - Valeur
  • S, U, V etc. - 2ème, 3ème, 4ème types

Vous verrez ces noms utilisés dans l'API Java SE et dans le reste de cette leçon.

Je m'y tenir pour éviter la confusion entre les développeurs et les éventuels responsables.

BalusC
la source
14
Le nouveau framework de flux utilise également Rpour le résultat et Apour l'accumulateur.
vandale
32
Blech, dénomination à une seule lettre. Je suis cette convention parce que la convention compte plus que les noms descriptifs, mais c'est triste que ce soit le mieux qu'ils puissent trouver.
warbaker
4
@warbaker: Je trouve que c'est un bon moyen de distinguer les types paramétrés des classes réelles. Comment diriez-vous autrement si, par exemple, Elementin List<Element>est un type paramétré ou une classe?
BalusC
1
Cela ne ressemble pas à BiFunction<T, U, R>cette convention. Si c'était le cas, ce serait le cas BiFunction<T, S, R>.
michaelsnowden
4
Pourquoi s'inquiéter de distinguer les types paramétrés des classes réelles? Ce sont des classes. Quoi qu'il en soit, vous devez faire défiler vers le haut quelque part dans le fichier pour savoir ce qu'ils sont définis. Et ce sera soit une importation, soit un type paramétré.
Vectorjohn
47

Ajouter Type

Une bonne discussion peut être trouvée dans les commentaires sur la page DZone, Conventions de dénomination pour les types paramétrés .

Voir le commentaire d'Erwin Mueller. Sa suggestion me paraît parfaitement logique: ajoutez le motType .

Appelez une pomme une pomme, une voiture une voiture. Le nom en question est le nom d'un type de données, non? (En POO , une classe définit essentiellement un nouveau type de données.) Appelez-le donc un «Type».

Exemple de Mueller, tiré de l'article de l'article original:

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

Ajouter T

Une question en double fournit cette réponse par Andy Thomas. Notez l'extrait du guide de style de Google qui suggère qu'un nom de type à plusieurs caractères doit se terminer par une seule majuscule T.

Basil Bourque
la source
3
J'aime cette réponse. L'ajout de "Type" est si clair et vous permet d'avoir des noms descriptifs. J'en ai marre des gens qui disent «faites-le parce que c'est la convention», sans autre justification. Si c'est une mauvaise convention, peut-être en avons-nous besoin d'une nouvelle.
Tiré
16

La raison pour laquelle la convention de dénomination officielle recommande l'utilisation d'une seule lettre est la suivante:

Sans cette convention, il serait difficile de faire la différence entre une variable de type et un nom de classe ou d'interface ordinaire.

Je pense qu'avec les IDE modernes, cette raison n'est plus valable, par exemple. IntelliJ Idea affiche des paramètres de type générique avec des couleurs différentes de celles des classes régulières.

Code de type générique tel qu'affiché dans IntelliJ Idea 2016.1 Code de type générique tel qu'affiché dans IntelliJ Idea 2016.1

En raison de cette distinction, j'utilise des noms descriptifs plus longs pour mes types génériques, avec la même convention que les types réguliers. J'évite d'ajouter des préfixes et des suffixes tels que T ou Type car je les considère comme du bruit inutile et ne sont plus nécessaires pour distinguer visuellement les types génériques.

Remarque: comme je ne suis pas un utilisateur d'Eclipse ou de Netbeans, je ne sais pas s'ils offrent une fonctionnalité similaire.

Vojtech Ruzicka
la source
Je ne baserais pas les conventions de dénomination sur les capacités supposées des outils que chaque personne lisant / modifiant ce même fichier aura. J'aime personnellement utiliser un éditeur de texte pour mon codage (Sublime Text) qui n'est pas un IDE. Les éditeurs de texte ont généralement de nos jours une coloration syntaxique, mais pas une compréhension approfondie de la structure de code sous-jacente qui, je pense, serait nécessaire pour colorer correctement les noms de variables. Et fonder cet argument sur la couleur est intrinsèquement exclusif aux personnes ayant une mauvaise vision des couleurs (je fais partie des 8% d'hommes atteints de daltonisme rouge-vert)
joonas.fi
1
Bon point concernant les personnes ayant une mauvaise vision des couleurs. En ce qui concerne ne pas utiliser les IDE - si les gens préfèrent utiliser de simples éditeurs de texte, c'est bien, mais ils sacrifient volontairement les fonctionnalités que les IDE leur offrent au profit d'un outil plus léger. Ce n'est peut-être qu'une de ces fonctionnalités manquantes. En fin de compte cependant, si un nom descriptif est utilisé au lieu d'une seule lettre, vous devriez être en mesure de dire la signification en fonction du nom sans IDE et sans code de couleur. Le codage couleur rend cela plus rapide.
Vojtech Ruzicka
16

Oui, vous pouvez utiliser des noms à plusieurs caractères pour les variables de type, à condition qu'ils se distinguent clairement des noms de classe.

Cela diffère de la convention suggérée par Sun avec l'introduction des génériques en 2004. Cependant:

  • Il existe plus d'une convention.
  • Les noms à plusieurs caractères sont cohérents avec d'autres styles Java, tels que le style de Google pour Java .
  • Les noms lisibles sont (surprise!) Plus lisibles.

Lisibilité

Dans certaines interfaces que j'ai écrites, j'aimerais nommer le paramètre de type générique avec plus d'un caractère pour rendre le code plus lisible.

La lisibilité est bonne.

Comparer:

    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> {

ou, avec la convention multi-caractères de 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> {

Style Google

Le guide de style Google Java autorise à la fois les noms à une seule lettre et les noms de classe à plusieurs caractères se terminant par T.

5.2.8 Saisir les noms de variables

Chaque variable de type est nommée dans l'un des deux styles suivants:

  • Une lettre majuscule unique, éventuellement suivie d'un chiffre unique (tels que E, T, X, T2)

  • Un nom sous la forme utilisée pour les classes (voir la section 5.2.2, noms de classes ), suivi de la lettre majuscule T (exemples: RequestT, FooBarT).

Problèmes

"Sans cette convention, il serait difficile de faire la différence entre une variable de type et un nom de classe ou d'interface ordinaire." - à partir des tutoriels Oracle, «Types génériques»

Les noms à caractère unique ne sont pas le seul moyen de distinguer les paramètres de type des noms de classe, comme nous l'avons vu ci-dessus.

Pourquoi ne pas simplement documenter la signification du paramètre de type dans le JavaDoc?

Il est vrai que les @paraméléments JavaDoc peuvent fournir une description plus longue. Mais il est également vrai que les JavaDocs ne sont pas forcément visibles. (Par exemple, il existe une assistance de contenu dans Eclipse qui affiche les noms des paramètres de type.)

Les noms de paramètres de type à plusieurs caractères ne suivent pas la convention Oracle!

De nombreuses conventions originales de Sun sont suivies presque universellement dans la programmation Java.

Cependant, cette convention particulière ne l'est pas.

Le meilleur choix parmi les conventions concurrentes est une question d’opinion. Les conséquences du choix d'une convention autre que celle d'Oracle dans ce cas sont mineures. Vous et votre équipe pouvez choisir la convention qui répond le mieux à vos besoins.

Andy Thomas
la source
15

Vous pouvez utiliser javadoc pour au moins donner un indice aux utilisateurs de votre classe générique. Je n'aime toujours pas ça (je suis d'accord avec @ chaper29) mais la documentation m'aide.

par exemple,

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

}

L'autre chose que j'ai connue est d'utiliser mon IDE pour refactoriser une classe qui enfreint la convention. Travaillez ensuite sur le code et remodelez-le en lettres simples. Cela me facilite de toute façon si de nombreux paramètres de type sont utilisés.

Tom Carchrae
la source
1
Je dirais que les commentaires Javadoc pour les paramètres de type sont généralement indispensables.
migu