Generische Namenskonvention für Typparameter für Java (mit mehreren Zeichen)?

124

In einigen von mir geschriebenen Schnittstellen möchte ich generische Typparameter mit mehr als einem Zeichen benennen, um den Code besser lesbar zu machen.

Etwas wie....

Map<Key,Value>

An Stelle von...

Map<K,V>

Aber wenn es um Methoden geht, sehen die Typparameter wie Java-Klassen aus, was ebenfalls verwirrend ist.

public void put(Key key, Value value)

Dies scheint, als wären Schlüssel und Wert Klassen. Ich fand oder dachte an einige Notationen, aber nichts wie eine Konvention von Sun oder eine allgemeine Best Practice.

Alternativen, die ich erraten oder gefunden habe ...

Map<KEY,VALUE>
Map<TKey,TValue>
chaper29
quelle
9
Warum möchten Sie eine neue Konvention erstellen?
Amir Afghani
13
@AmirAfghani Aus der Frage: Um den Code lesbarer zu machen.
SantiBailors
Technisch gesehen sollte der unterschiedliche Farbton der Generika in der IDE als ausreichend guter Indikator dienen
Sudix

Antworten:

181

Oracle empfiehlt unter Java Tutorials> Generics> Generic Types Folgendes :

Geben Sie Parameter-Namenskonventionen ein

Konventionell sind Typparameternamen einzelne Großbuchstaben. Dies steht in scharfem Kontrast zu den Konventionen zur Benennung von Variablen , die Sie bereits kennen, und das aus gutem Grund: Ohne diese Konvention wäre es schwierig, den Unterschied zwischen einer Typvariablen und einem normalen Klassen- oder Schnittstellennamen zu erkennen.

Die am häufigsten verwendeten Typparameternamen sind:

  • E-Element (wird häufig vom Java Collections Framework verwendet)
  • K - Schlüssel
  • N - Nummer
  • T - Typ
  • V - Wert
  • S, U, V usw. - 2., 3., 4. Typ

Diese Namen werden in der gesamten Java SE-API und im Rest dieser Lektion verwendet.

Ich würde mich daran halten, um die Verwirrung zwischen den Entwicklern und möglichen Betreuern zu vermeiden.

BalusC
quelle
14
Das neue Stream-Framework wird auch Rfür das Ergebnis und Afür den Akkumulator verwendet.
Vandale
32
Blech, Einzelbuchstaben. Ich folge dieser Konvention, weil Konvention mehr zählt als beschreibende Namen, aber es ist traurig, dass dies das Beste ist, was sie sich einfallen lassen können.
Warbaker
4
@warbaker: Ich finde es eine gute Möglichkeit, parametrisierte Typen von tatsächlichen Klassen zu unterscheiden. Wie würden Sie sonst feststellen, ob z. B. Elementin List<Element>ein parametrisierter Typ oder eine Klasse ist?
BalusC
1
Es sieht nicht so aus, als würde man BiFunction<T, U, R>dieser Konvention folgen. Wenn es so wäre, wäre es so BiFunction<T, S, R>.
michaelsnowden
4
Warum die Sorge, parametrisierte Typen von tatsächlichen Klassen zu unterscheiden? Sie sind Klassen. Egal was passiert, Sie müssen irgendwo in der Datei nach oben scrollen, um herauszufinden, als was sie definiert sind. Und es wird entweder ein Import oder ein parametrisierter Typ sein.
Vectorjohn
47

Anhängen Type

Eine gute Diskussion finden Sie in den Kommentaren auf der DZone-Seite, Namenskonventionen für parametrisierte Typen .

Siehe den Kommentar von Erwin Müller. Sein Vorschlag macht für mich ganz offensichtlich Sinn: Fügen Sie das Wort hinzuType .

Nennen Sie einen Apfel einen Apfel, ein Auto ein Auto. Der fragliche Name ist der Name eines Datentyps, oder? (In OOP definiert eine Klasse im Wesentlichen einen neuen Datentyp.) Nennen Sie ihn also "Typ".

Muellers Beispiel aus dem Artikel des Originalposts:

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

Anhängen T

Eine doppelte Frage liefert diese Antwort von Andy Thomas. Beachten Sie den Auszug aus dem Google-Styleguide, der vorschlägt, dass ein mehrstelliger Typname in einem einzigen Großbuchstaben enden sollte T.

Basil Bourque
quelle
3
Ich mag diese Antwort. Das Hinzufügen von "Typ" ist so klar und ermöglicht Ihnen beschreibende Namen. Ich habe es satt, dass Leute sagen: "Tu es, weil es die Konvention ist", ohne andere Rechtfertigung. Wenn es eine schlechte Konvention ist, brauchen wir vielleicht eine neue.
Drew
16

Der Grund, warum die offizielle Namenskonvention die Verwendung eines einzelnen Buchstabens empfiehlt, ist folgender:

Ohne diese Konvention wäre es schwierig, den Unterschied zwischen einer Typvariablen und einem normalen Klassen- oder Schnittstellennamen zu erkennen.

Ich denke, mit modernen IDEs ist dieser Grund nicht mehr gültig, wie z. IntelliJ Idea zeigt generische Typparameter mit anderen Farben als reguläre Klassen an.

Code mit generischem Typ, wie in IntelliJ Idea 2016.1 angezeigt Code mit generischem Typ, wie in IntelliJ Idea 2016.1 angezeigt

Aufgrund dieser Unterscheidung verwende ich für meine generischen Typen längere beschreibende Namen mit derselben Konvention wie reguläre Typen. Ich vermeide das Hinzufügen von Präfixen und Suffixen wie T oder Type, da ich sie als unnötiges Rauschen betrachte und nicht mehr zur visuellen Unterscheidung generischer Typen benötige.

Hinweis: Da ich kein Benutzer von Eclipse oder Netbeans bin, weiß ich nicht, ob sie eine ähnliche Funktion bieten.

Vojtech Ruzicka
quelle
Ich würde Namenskonventionen nicht auf angenommenen Fähigkeiten der Tools basieren, über die jede Person, die jemals dieselbe Datei liest / ändert, verfügen wird. Ich persönlich verwende gerne einen Texteditor für meine Codierung (Sublime Text), der keine IDE ist. Texteditoren haben heutzutage normalerweise eine Syntaxfarbe, aber kein tiefes Verständnis der zugrunde liegenden Codestruktur, die meiner Meinung nach erforderlich wäre, um Variablennamen vom Typ korrekt zu färben. Und dieses Argument auf die Farbe zu stützen, ist von Natur aus exklusiv für Menschen mit schlechtem Farbsehen (ich bin Teil der 8% der Männer mit rot-grüner Farbenblindheit)
joonas.fi
1
Guter Punkt in Bezug auf Menschen mit schlechtem Farbsehen. Wenn Sie keine IDEs verwenden - wenn Benutzer einfache Texteditoren bevorzugen, ist dies in Ordnung, aber sie opfern freiwillig die Funktionen, die IDEs ihnen bieten, zugunsten eines leichteren Tools. Dies ist möglicherweise nur eine dieser fehlenden Funktionen. Wenn jedoch anstelle eines einzelnen Buchstabens ein beschreibender Name verwendet wird, sollten Sie in der Lage sein, die Bedeutung anhand des Namens ohne IDE und ohne Farbcodierung zu ermitteln. Die Farbcodierung macht dies nur schneller.
Vojtech Ruzicka
16

Ja, Sie können mehrstellige Namen für Typvariablen verwenden, sofern diese klar von Klassennamen unterschieden werden.

Dies unterscheidet sich von der von Sun mit der Einführung von Generika im Jahr 2004 vorgeschlagenen Konvention. Allerdings:

  • Es gibt mehr als eine Konvention.
  • Namen mit mehreren Zeichen stimmen mit anderen Java-Stilen überein, z. B. dem Google-Stil für Java .
  • Die lesbaren Namen sind (Überraschung!) Besser lesbar.

Lesbarkeit

In einigen von mir geschriebenen Schnittstellen möchte ich generische Typparameter mit mehr als einem Zeichen benennen, um den Code besser lesbar zu machen.

Die Lesbarkeit ist gut.

Vergleichen Sie:

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

zu:

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

oder mit der Mehrzeichenkonvention von 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-Stil

Der Google Java Style Guide ermöglicht sowohl Einzelbuchstaben als auch Klassen mit mehreren Zeichen, die mit T enden.

5.2.8 Variablennamen eingeben

Jede Typvariable wird in einem von zwei Stilen benannt:

  • Ein einzelner Großbuchstabe, die gegebenenfalls durch eine einzige Ziffer gefolgt (wie zum Beispiel E, T, X, T2)

  • Ein Name in der Form für die Klassen verwendet (Abschnitt 5.2.2, siehe Klassennamen ), gefolgt von den Großbuchstaben T (Beispiele: RequestT, FooBarT).

Probleme

"Ohne diese Konvention wäre es schwierig, den Unterschied zwischen einer Typvariablen und einem normalen Klassen- oder Schnittstellennamen zu erkennen." - aus den Oracle-Tutorials "Generische Typen"

Einzelzeichennamen sind nicht die einzige Möglichkeit, Typparameter von Klassennamen zu unterscheiden, wie wir oben gesehen haben.

Warum nicht einfach die Bedeutung der Typparameter im JavaDoc dokumentieren?

Es ist wahr, dass die @paramJavaDoc-Elemente eine längere Beschreibung liefern können. Es stimmt aber auch, dass die JavaDocs nicht unbedingt sichtbar sind. (Zum Beispiel gibt es in Eclipse eine Inhaltshilfe, die die Namen der Typparameter anzeigt.)

Parameternamen mit mehreren Zeichen entsprechen nicht der Oracle-Konvention!

Viele der ursprünglichen Konventionen von Sun werden in der Java-Programmierung nahezu universell befolgt.

Diese spezielle Konvention ist es jedoch nicht.

Die beste Wahl unter konkurrierenden Konventionen ist Ansichtssache. Die Konsequenzen der Wahl einer anderen Konvention als der von Oracle sind in diesem Fall gering. Sie und Ihr Team können eine Konvention auswählen, die Ihren Anforderungen am besten entspricht.

Andy Thomas
quelle
15

Sie können javadoc verwenden, um zumindest Benutzern Ihrer generischen Klasse einen Hinweis zu geben. Ich mag es immer noch nicht (ich stimme @ chaper29 zu), aber die Dokumente helfen.

z.B,

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

}

Das andere, von dem ich bekannt bin, ist, meine IDE zu verwenden, um eine Klasse umzugestalten, die gegen die Konvention verstößt. Arbeiten Sie dann am Code und überarbeiten Sie ihn wieder in einzelne Buchstaben. Macht es mir sowieso leichter, wenn viele Typparameter verwendet werden.

Tom Carchrae
quelle
1
Ich würde sagen, dass Javadoc-Kommentare für Typparameter normalerweise ein Muss sind.
Migu