Convenzione di denominazione dei parametri di tipo generico per Java (con più caratteri)?


125

In alcune interfacce che ho scritto vorrei nominare parametri di tipo generico con più di un carattere per rendere il codice più leggibile.

Qualcosa di simile a....

Map<Key,Value>

Invece di questo...

Map<K,V>

Ma quando si tratta di metodi, i parametri di tipo sembrano classi java, il che crea confusione.

public void put(Key key, Value value)

Sembra che Key e Value siano classi. Ho trovato o pensato ad alcune annotazioni, ma niente come una convenzione di Sun o una best practice generale.

Alternative che ho immaginato o trovato ...

Map<KEY,VALUE>
Map<TKey,TValue>

9
Perché vuoi creare una nuova convenzione?
Amir Afghani

13
@AmirAfghani Dalla domanda: per rendere il codice più leggibile.
SantiBailors

Tecnicamente, la diversa tonalità dei generici nell'IDE dovrebbe servire da indicatore abbastanza buono
Sudix

Risposte:


182

Oracle consiglia quanto segue in Tutorial Java> Generics> Tipi generici :

Tipo Convenzioni di denominazione dei parametri

Per convenzione, i nomi dei parametri di tipo sono lettere maiuscole singole. Ciò è in netto contrasto con le convenzioni di denominazione delle variabili che già conosci, e per una buona ragione: senza questa convenzione, sarebbe difficile distinguere tra una variabile di tipo e un nome di classe o interfaccia ordinario.

I nomi dei parametri di tipo più comunemente usati sono:

  • E - Element (ampiamente utilizzato da Java Collections Framework)
  • K-Key
  • N - Numero
  • T - Tipo
  • V - Valore
  • S, U, V ecc. - 2 °, 3 °, 4 ° tipo

Vedrai questi nomi usati in tutta l'API di Java SE e nel resto di questa lezione.

Mi atterrei per evitare la confusione tra sviluppatori e possibili manutentori.


14
Il nuovo framework stream utilizza anche Rper il risultato e Aper l'accumulatore.
vandale

32
Blech, denominazione di una sola lettera. Seguo questa convenzione perché la convenzione conta più dei nomi descrittivi, ma è triste che questo sia il meglio che potrebbero inventare.
warbaker

4
@warbaker: trovo che sia un buon modo per distinguere i tipi parametrizzati dalle classi effettive. Come diresti altrimenti se ad esempio Elementin List<Element>è un tipo parametrizzato o una classe?
BalusC

1
Non sembra che BiFunction<T, U, R>segua questa convenzione. Se lo facesse, lo sarebbe BiFunction<T, S, R>.
michaelsnowden

4
Perché preoccuparsi di distinguere i tipi parametrizzati dalle classi effettive? Essi sono classi. Non importa cosa, devi scorrere verso l'alto da qualche parte nel file per scoprire come sono definiti. E sarà un'importazione o un tipo parametrizzato.
Vectorjohn

47

Aggiungere Type

Una buona discussione può essere trovata nei commenti sulla pagina DZone, Naming Conventions for Parameterized Types .

Vedi il commento di Erwin Mueller. Il suo suggerimento ha perfettamente senso per me: aggiungi la parolaType .

Chiama una mela una mela, una macchina un'auto. Il nome in questione è il nome di un tipo di dati, giusto? (In OOP , una classe definisce essenzialmente un nuovo tipo di dati.) Quindi chiamatela "Tipo".

L'esempio di Mueller, tratto dall'articolo del post originale:

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

Aggiungere T

Una domanda duplicata fornisce questa risposta di Andy Thomas. Nota l'estratto dalla guida di stile di Google che suggerisce che un nome di tipo multi-carattere dovrebbe terminare con una singola maiuscola T.


3
Mi piace questa risposta. L'aggiunta di "Tipo" è molto chiara e ti consente di avere nomi descrittivi. Sono stufo di persone che dicono "fallo perché è la convenzione" senza altra giustificazione. Se è una cattiva convenzione, forse ce ne serve una nuova.
Drew

16

Il motivo per cui la convenzione di denominazione ufficiale consiglia di utilizzare una singola lettera è il seguente:

Senza questa convenzione, sarebbe difficile stabilire la differenza tra una variabile di tipo e un nome di classe o interfaccia ordinario.

Penso che con gli IDE moderni la ragione non sia più valida come ad es. IntelliJ Idea mostra parametri di tipo generico con colori diversi rispetto alle classi normali.

Codice con tipo generico come visualizzato in IntelliJ Idea 2016.1 Codice con tipo generico come visualizzato in IntelliJ Idea 2016.1

A causa di questa distinzione utilizzo nomi descrittivi più lunghi per i miei tipi generici, con la stessa convenzione dei tipi normali. Evito di aggiungere prefissi e suffissi come T o Type poiché li considero rumore non necessario e non più necessari per distinguere visivamente i tipi generici.

Nota: poiché non sono un utente di Eclipse o Netbeans, non so se offrono una funzionalità simile.


Non baserei le convenzioni di denominazione sulle capacità presunte degli strumenti che ogni persona che leggerà / modificherà lo stesso file avrà. Personalmente mi piace usare un editor di testo per la mia codifica (Sublime Text) che non è un IDE. Gli editor di testo di solito al giorno d'oggi hanno la colorazione della sintassi, ma non una profonda comprensione della struttura del codice sottostante che penso sarebbe necessaria per colorare correttamente i nomi delle variabili di tipo. E basare questo argomento sul colore è intrinsecamente esclusivo per le persone con scarsa visione dei colori (faccio parte dell'8% dei maschi con
daltonismo

1
Buon punto per quanto riguarda le persone con scarsa visione dei colori. Per quanto riguarda il non utilizzo degli IDE, se le persone preferiscono utilizzare semplici editor di testo, va bene, ma sacrificano volontariamente le funzionalità che gli IDE offrono loro a favore di uno strumento più leggero. Questa potrebbe essere solo una di quelle caratteristiche mancanti. Alla fine, però, se viene utilizzato un nome descrittivo invece di una singola lettera, dovresti essere in grado di dire il significato in base al nome senza un IDE e senza il codice colore. La codifica a colori rende tutto più veloce.
Vojtech Ruzicka

16

Sì, puoi usare nomi multi-carattere per variabili di tipo, purché siano chiaramente distinti dai nomi di classe.

Ciò differisce dalla convenzione suggerita da Sun con l'introduzione dei generici nel 2004. Tuttavia:

  • Esiste più di una convenzione.
  • I nomi composti da più caratteri sono coerenti con altri stili Java, come lo stile di Google per Java .
  • I nomi leggibili sono (sorpresa!) Più leggibili.

leggibilità

In alcune interfacce che ho scritto vorrei nominare un parametro di tipo generico con più di un carattere per rendere il codice più leggibile.

La leggibilità è buona.

Confrontare:

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

per:

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

oppure, con la convenzione multi-carattere di 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> {

Stile Google

La Guida allo stile di Google Java consente sia nomi di una sola lettera che nomi di classe multi-carattere che terminano con T.

5.2.8 Digitare i nomi delle variabili

Ogni variabile di tipo è denominata in uno dei due stili:

  • Una singola lettera maiuscola, eventualmente seguito da un singolo numero di riferimento (ad esempio E, T, X, T2)

  • Un nome nella forma utilizzata per le classi (vedere Sezione 5.2.2, nomi di classe ), seguito dalla lettera maiuscola T (esempi: RequestT, FooBarT).

Problemi

"Senza questa convenzione, sarebbe difficile distinguere tra una variabile di tipo e un nome di classe o interfaccia ordinario." - dai tutorial Oracle, "Tipi generici"

I nomi a carattere singolo non sono l'unico modo per distinguere i parametri di tipo dai nomi di classe, come abbiamo visto sopra.

Perché non documentare semplicemente il significato del parametro di tipo in JavaDoc?

È vero che gli @paramelementi JavaDoc possono fornire una descrizione più lunga. Ma è anche vero che i JavaDoc non sono necessariamente visibili. (Ad esempio, c'è un'assistenza ai contenuti in Eclipse che mostra i nomi dei parametri di tipo.)

I nomi dei parametri di tipo multi-carattere non seguono la convenzione Oracle!

Molte delle convenzioni originali di Sun sono seguite quasi universalmente nella programmazione Java.

Tuttavia, questa particolare convenzione non lo è.

La scelta migliore tra le convenzioni concorrenti è una questione di opinione. Le conseguenze della scelta di una convenzione diversa da quella di Oracle in questo caso sono minori. Tu e il tuo team potete scegliere la convenzione che meglio soddisfa le vostre esigenze.


15

Puoi usare javadoc almeno per dare un indizio agli utenti della tua classe generica. Ancora non mi piace (sono d'accordo con @ chaper29) ma i documenti aiutano.

per esempio,

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

}

L'altra cosa che so fare è usare il mio IDE per refactoring di una classe che infrange la convenzione. Quindi lavora sul codice e ricalcola le singole lettere. Mi rende comunque più facile l'utilizzo di molti parametri di tipo.


1
Direi che i commenti Javadoc per i parametri di tipo sono di solito un must.
migu
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.