¿Convención de nomenclatura de parámetros de tipo genérico para Java (con múltiples caracteres)?

124

En algunas interfaces que escribí, me gustaría nombrar parámetros de tipo genérico con más de un carácter para que el código sea más legible.

Algo como....

Map<Key,Value>

En lugar de esto...

Map<K,V>

Pero cuando se trata de métodos, los parámetros de tipo se parecen a las clases java, lo que también es confuso.

public void put(Key key, Value value)

Esto parece que Key y Value son clases. Encontré o pensé en algunas anotaciones, pero nada como una convención de Sun o una mejor práctica general.

Alternativas que adiviné o encontré ...

Map<KEY,VALUE>
Map<TKey,TValue>
chaper29
fuente
9
¿Por qué quieres crear una nueva convención?
Amir Afghani
13
@AmirAfghani De la pregunta: para hacer que el código sea más legible.
SantiBailors
Técnicamente, el tono diferente de los genéricos en el IDE debería servir como un indicador lo suficientemente bueno
Sudix

Respuestas:

181

Oracle recomienda lo siguiente en Tutoriales de Java> Genéricos> Tipos genéricos :

Convenciones de nomenclatura de parámetros de tipo

Por convención, los nombres de parámetros de tipo son letras mayúsculas individuales. Esto contrasta fuertemente con el nombre variable convenciones de que ya conoce, y con una buena razón: sin esta convención, sería difícil distinguir entre una variable de tipo y una clase ordinaria o nombre de interfaz.

Los nombres de parámetros de tipo más utilizados son:

  • E - Elemento (utilizado ampliamente por el marco de colecciones de Java)
  • K - Clave
  • N - Número
  • T - Tipo
  • V - Valor
  • S, U, V etc. - 2do, 3ro, 4to tipos

Verá estos nombres utilizados en la API Java SE y el resto de esta lección.

Me apegaría a ello para evitar la confusión entre los desarrolladores y posibles mantenedores.

BalusC
fuente
14
El nuevo marco de transmisión también se utiliza Rpara el resultado y Apara el acumulador.
vandale
32
Blech, nombres de una letra. Sigo esta convención porque la convención es más importante que los nombres descriptivos, pero es triste que sea lo mejor que se les haya ocurrido.
warbaker
44
@warbaker: me parece una buena manera de distinguir los tipos parametrizados de las clases reales. ¿Cómo podría saber si, por ejemplo, Elementin List<Element>es un tipo parametrizado o una clase?
BalusC
1
No parece que BiFunction<T, U, R>siga esta convención. Si lo hiciera, lo sería BiFunction<T, S, R>.
michaelsnowden
44
¿Por qué preocuparse por distinguir los tipos parametrizados de las clases reales? Ellos son clases. Pase lo que pase, debe desplazarse hacia arriba en algún lugar del archivo para averiguar cómo se definen. Y será una importación o un tipo parametrizado.
Vectorjohn
47

Adjuntar Type

Se puede encontrar una buena discusión en los comentarios en la página DZone, Convenciones de nomenclatura para tipos parametrizados .

Ver el comentario de Erwin Mueller. Su sugerencia tiene mucho sentido para mí: anexar la palabraType .

Llame a una manzana una manzana, un auto un auto El nombre en cuestión es el nombre de un tipo de datos, ¿verdad? (En OOP , una clase esencialmente define un nuevo tipo de datos). Así que llámelo "Tipo".

El ejemplo de Mueller, extraído del artículo de la publicación original:

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

Adjuntar T

Una pregunta duplicada proporciona esta respuesta por Andy Thomas. Tenga en cuenta el extracto de la guía de estilo de Google que sugiere que un nombre de tipo de varios caracteres debe terminar en mayúscula T.

Albahaca Bourque
fuente
3
Me gusta esta respuesta Agregar "Tipo" es muy claro y le permite tener nombres descriptivos. Estoy harto de que la gente diga "hazlo porque es la convención", sin otra justificación. Si es una mala convención, tal vez necesitemos una nueva.
Dibujó el
16

La razón por la cual la convención oficial de nombres recomienda el uso de una sola letra es la siguiente:

Sin esta convención, sería difícil distinguir entre una variable de tipo y una clase ordinaria o nombre de interfaz.

Creo que con los IDE modernos esa razón ya no es válida, por ejemplo. IntelliJ Idea muestra parámetros de tipo genérico con diferentes colores que las clases regulares.

Código con tipo genérico como se muestra en IntelliJ Idea 2016.1 Código con tipo genérico como se muestra en IntelliJ Idea 2016.1

Debido a esa distinción , uso nombres descriptivos más largos para mis tipos genéricos, con la misma convención que los tipos normales. Evito agregar prefijos y sufijos como T o Type porque los considero ruidos innecesarios y ya no necesito distinguir visualmente los tipos genéricos.

Nota: Como no soy usuario de Eclipse o Netbeans, no sé si ofrecen una función similar.

Vojtech Ruzicka
fuente
No basaría las convenciones de nomenclatura en torno a las capacidades asumidas de las herramientas que cada persona leerá / modificará ese mismo archivo. Personalmente, me gusta usar un editor de texto para mi codificación (Sublime Text) que no es un IDE. Los editores de texto generalmente tienen hoy en día un color de sintaxis, pero no una comprensión profunda de la estructura de código subyacente que creo que sería necesaria para colorear correctamente los nombres de variables de tipo. Y basar este argumento en el color es inherentemente exclusivo para las personas con mala visión del color (soy parte del 8% de los hombres con ceguera al color rojo-verde)
joonas.fi
1
Buen punto con respecto a las personas con mala visión del color. Con respecto a no usar IDE: si las personas prefieren usar editores de texto simples, está bien, pero sacrifican voluntariamente las características que los IDE les ofrecen en favor de una herramienta más liviana. Esta puede ser solo una de esas características que faltan. Sin embargo, al final, si se usa un nombre descriptivo en lugar de una sola letra, debería poder decir el significado en función del nombre sin un IDE y sin la codificación de colores. La codificación de colores solo lo hace más rápido.
Vojtech Ruzicka
16

Sí, puede usar nombres de varios caracteres para las variables de tipo, siempre que se distingan claramente de los nombres de clase.

Esto difiere de la convención sugerida por Sun con la introducción de genéricos en 2004. Sin embargo:

  • Existe más de una convención.
  • Los nombres de varios caracteres son consistentes con otros estilos de Java, como el estilo de Google para Java .
  • Los nombres legibles son (¡sorpresa!) Más legibles.

Legibilidad

En algunas interfaces que escribí, me gustaría nombrar un parámetro de tipo genérico con más de un carácter para que el código sea más legible.

La legibilidad es buena.

Comparar:

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

a:

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

o, con la convención de caracteres múltiples 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> {

Estilo de Google

La Guía de estilo de Java de Google permite nombres de una sola letra y nombres de clase de varios caracteres que terminan en T.

5.2.8 Escriba nombres de variables

Cada variable de tipo se nombra en uno de dos estilos:

  • Una letra mayúscula solo, seguido opcionalmente por un solo número (tales como E, T, X, T2)

  • Un nombre en la forma utilizada para las clases (ver Sección 5.2.2, nombres de clase ), seguido de la letra mayúscula (por ejemplo: RequestT, FooBarT).

Cuestiones

"Sin esta convención, sería difícil distinguir entre una variable de tipo y un nombre de clase o interfaz ordinario". - de los tutoriales de Oracle, "Tipos genéricos"

Los nombres de un solo carácter no son la única forma de distinguir los parámetros de tipo de los nombres de clase, como hemos visto anteriormente.

¿Por qué no simplemente documentar el significado del parámetro de tipo en JavaDoc?

Es cierto que los @paramelementos JavaDoc pueden proporcionar una descripción más larga. Pero también es cierto que los JavaDocs no son necesariamente visibles. (Por ejemplo, hay un asistente de contenido en Eclipse que muestra los nombres de los parámetros de tipo).

¡Los nombres de parámetros de tipo de caracteres múltiples no siguen la convención de Oracle!

Muchas de las convenciones originales de Sun se siguen casi universalmente en la programación Java.

Sin embargo, esta convención particular no lo es.

La mejor opción entre las convenciones en competencia es una cuestión de opinión. Las consecuencias de elegir una convención diferente a la de Oracle en este caso son menores. Usted y su equipo pueden elegir la convención que mejor satisfaga sus necesidades.

Andy Thomas
fuente
15

Puede usar javadoc para dar al menos una pista a los usuarios de su clase genérica. Todavía no me gusta (estoy de acuerdo con @ chaper29) pero los documentos ayudan.

p.ej,

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

}

La otra cosa que he sabido hacer es usar mi IDE para refactorizar una clase que rompe la convención. Luego trabaje en el código y refactorice a letras individuales. De todos modos, me resulta más fácil si se utilizan muchos parámetros de tipo.

Tom Carchrae
fuente
1
Yo diría que los comentarios Javadoc para los parámetros de tipo son generalmente obligatorios.
migu