Briser la convention de nommage des génériques java? [dupliquer]
Cette question a déjà une réponse ici:
- convention de nommage de paramètre de type générique pour Java (avec plusieurs caractères)? 5 réponses
J'ai une interface dont la déclaration est la suivante:
/**
* @param T - the type of entity.
* @param C - the type of entity container will be returned.
*/
public interface FindByNamedQuery<T extends Serializable, C extends Collection<T>> extends Command {
C executeNamedQuery(String namedQuery);
}
Je me demande si je peux (devrais) casser la convention de nommage Java pour faire ceci:
public interface FindByNamedQuery<ENTITY_TYPE extends Serializable, RETURNED_CONTAINER extends Collection<ENTITY_TYPE>> extends Command {
RETURNED_CONTAINER executeNamedQuery(String namedQuery);
}
7 réponses
Je commence à être en désaccord avec la convention à caractère unique, après l'avoir utilisée depuis le milieu des années 1990.
Je trouve les noms lisibles plus lisibles. Ceci est utile pour comprendre à la fois l'implémentation et l'interface des types génériques.
Le problème d'ambiguïté semble exagéré pour Java. Quelques noms de classe sont en majuscules. Les constantes ne sont pas utilisées dans le même contexte que les noms de classes.
Il est vrai que les éléments @ param JavaDoc peuvent fournir une description plus longue. Mais il est également vrai que les JavaDocs ne sont pas nécessairement visibles. (Par exemple, il existe une aide au contenu dans Eclipse qui affiche les noms des paramètres de type.)
Par exemple, comparez:
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> {
Bien que les noms à caractère unique aient été recommandés comme convention par Sun / Oracle, les conventions peuvent être modifiées. Les conséquences de la contestation de cette convention sont mineures. Si vous et votre équipe préférez des noms significatifs pour vos paramètres de type, personnellement, j'irais pour il.
Modifier (2015)
Google style for Java permet à la fois des noms à une seule lettre et des noms de classe à caractères multiples se terminant par T.
5.2.8 Tapez les noms de variables
Chaque variable de type est nommée dans l'un des deux styles suivants:
Une seule lettre majuscule, éventuellement suivie d'un seul chiffre (tel que E, T, X, T2)
Un nom sous la forme utilisée pour les classes (voir Section 5.2.2, noms de classes), suivi de la lettre majuscule T (exemples: RequestT, FooBarT).
je me demande si je peux (devrais) casser la convention de nommage java pour le faire:
Non, cela devrait être évité car il devient plus facile de confondre les paramètres de type avec des constantes et d'autres identificateurs.
Voici une citation de la piste officielle sur les génériques :
Conventions De Nommage Des Paramètres De Type
par convention, les noms de paramètres de type sont simples, majuscules lettres. Cela contraste fortement avec les conventions de nommage des variables que vous connaissez déjà, et pour cause: 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
- Élément (largement utilisé par le Java Collections Cadre)K
- CléN
- NombreT
- TypeV
- ValeurS
,U
,V
etc. - 2ème, 3ème, 4ème typesvous verrez ces noms utilisés tout au long de L'API Java SE et le reste de ce tutoriel.
L'utilisation de TDescription est assez courante en C#. Il conserve le nom T mais est également descriptif en même temps, comme ceci:
public interface FindByNamedQuery<
TEntityType extends Serialiazble,
TReturnedContainer extends Collections<TEntityType>> extends Command
{
TReturnedContainer executeNamedQuery(String namedQuery);
}
, Comme d'autres l'ont dit ALL_CAPS
indique presque toujours une constante.
IMO, "Il serait difficile de faire la différence entre une variable de type et un nom de classe ou d'interface ordinaire." ne s'applique pas ici, car le préfixe T l'identifie facilement comme une variable de type.
Encore une fois, c'est C# mais voir MSDN: conventions de nommage pour Les génériques
Dans tous les autres cas, le fonctionnaire Directives Microsoft pour generic les conventions de nommage sont:
Nom des paramètres de type générique avec des noms descriptifs, sauf si lettre nom est complètement auto explicatif et un nom descriptif ne serait pas ajouter de la valeur.
public interface ISessionChannel<TSession> {...} public delegate TOutput Converter<TInput,TOutput>(TInput from);
- pensez à indiquer les contraintes placées sur un paramètre de type dans le nom du paramètre. Par exemple, un paramètre contraint à ISession peut être appelé TSession.
Le compilateur peut ne pas se plaindre, mais vos coéquipiers peuvent ne pas vous apprécier en utilisant ce qui semble être une constante dans un endroit où ils attendent un paramètre de type.
Je pense que c'est le reproche de beaucoup de gens qui utilisent des génériques. Je ne suis pas tout à fait d'accord avec la déclaration de Sun selon laquelle si vous utilisez un nom à part entière, il sera confondu avec un nom de classe existant ou autre chose. Dans ce cas, nous pouvons commencer le nom de l'espace réservé avec un dollar comme ceci:
public class HashMap<$Key,$Value> implements Map<$Key,$Value>{}
Personne dans leur esprit sain d'esprit ne nomme une classe commençant par un signe dollar. Et un signe dollar est également utilisé pour désigner un espace réservé de nombreux langages de modèles velocity, struts, spring, etc. Je pense que c'est le chemin à parcourir.
J'ai plus de détails à ce sujet et le raisonnement derrière ne pas avoir à utiliser une seule notation de lettre dans mon blog si quelqu'un est intéressé.
Http://readsethu.wordpress.com/2012/05/23/a-generic-class-and-why-is-it-confusing/
Comme Allen avant , mon conseil vient plus de C# (que j'utilise beaucoup depuis 5 mois) que de Java (avec lequel j'ai joué, mais ça n'est jamais allé très loin...), mais je trouve le code Java et C# assez similaire dans l'esprit (c'est-à-dire comparé par, disons, C++)
Quoi qu'il en soit, lorsque vous utilisez un générique C#/Java (ou un modèle C++) sur un type simple, j'utilise généralement T:
// C++
template<typename T>
class MyClass { /* ... */ } ;
// C#
public MyClass<T> { /* etc. */ }
// Java
public MyClass<T> { /* etc. */ }
Habituellement, le type T va avec la classe, donc il n'est pas nécessaire de le décrire plus.
Mais quand vraiment décrire le type ajoute à la clarté du code, je le fais.
Ou quand j'ai deux types ou plus dans la même déclaration Générique / modèle, cela aide à faire la différence entre deux types. Par exemple (exemple réel en C#) :
// C++
template<typename T_Data, typename T_Underlying>
class MyClass { /* ... */ } ;
// C#
public MyClass<T_Data, T_Underlying> { /* etc. */ }
// Java
public MyClass<T_Data, T_Underlying> { /* etc. */ }
De cette façon, il est facile de faire la différence entre les deux noms de type dans le code, où T
et U
sont, Eh bien... un peu anonyme: pour ceux qui utilisent Visual C++, aller dans le débogage dans le code STL de Dinkumware, plein de T
, _U
, et autres les noms de type mono-lettre peuvent être assez frustrants... Je suppose que la même chose vaut pour le code C# ou Java.
Vous noterez que dans chaque cas (c++, Java ou C#), Je ne suis pas la convention quelque part dans Mes noms de type: la raison en est que parfois, il suffit d'essayer autre chose au lieu de suivre le troupeau, même si à la fin, vous vous tromperez.
Dans le cas présent, la violation de la convention de nommage n'est pas critique (il y a les pires problèmes en Java que ce petit crime), et à la toute fin, vous apprendrez personnellement et exactement pourquoi c'est faux, au lieu de citer de vieux documents.
Et si vous trouvez à la fin, vous avez raison, Eh bien...
Je nommerais des variables de type similaires aux types, dans le boîtier de chameau, mais préfixées par"_".
public interface FindByNamedQuery
<_EntityType extends Serialiazble,
_ReturnedContainer extends Collections<_EntityType>>
extends Command
{
_ReturnedContainer executeNamedQuery(String namedQuery);
}