Konwencja nazewnictwa parametrów typu ogólnego dla języka Java (z wieloma znakami)?

125

W niektórych interfejsach, które napisałem, chciałbym nazwać parametry typu ogólnego z więcej niż jednym znakiem, aby kod był bardziej czytelny.

Coś jak....

Map<Key,Value>

Zamiast tego...

Map<K,V>

Ale jeśli chodzi o metody, parametry typu wyglądają jak klasy java, co również jest mylące.

public void put(Key key, Value value)

Wygląda na to, że klucz i wartość to klasy. Znalazłem lub pomyślałem o pewnych zapisach, ale nie przypominają one konwencji Sun lub ogólnej najlepszej praktyki.

Alternatywy, które zgadłem lub znalazłem ...

Map<KEY,VALUE>
Map<TKey,TValue>
opiekun29
źródło
9
Dlaczego chcesz stworzyć nową konwencję?
Amir Afghani
13
@AmirAfghani Z pytania: uczynić kod bardziej czytelnym.
SantiBailors
Technicznie rzecz biorąc, inny odcień leków generycznych w IDE powinien służyć jako wystarczająco dobry wskaźnik
Sudix

Odpowiedzi:

182

Firma Oracle zaleca w sekcji Samouczki języka Java> Ogólne> Typy ogólne :

Konwencje nazewnictwa parametrów typu

Zgodnie z konwencją nazwy parametrów typu to pojedyncze wielkie litery. Kontrastuje to ostro z konwencjami nazewnictwa zmiennych , o których już wiesz, i nie bez powodu: bez tej konwencji trudno byłoby odróżnić zmienną typu od zwykłej nazwy klasy lub interfejsu.

Najczęściej używane nazwy parametrów typu to:

  • E - Element (szeroko używany w Java Collections Framework)
  • K - klucz
  • N - liczba
  • T - typ
  • V - wartość
  • S, U, V itd. - 2, 3, 4 typy

Nazwy te będą używane w całym API Java SE i w pozostałej części tej lekcji.

Trzymałbym się tego, aby uniknąć zamieszania wśród programistów i ewentualnych opiekunów.

BalusC
źródło
14
Nowa struktura strumieniowa używa również Rwyników i Aakumulatora.
vandale
32
Blech, nazewnictwo jednoliterowe. Przestrzegam tej konwencji, ponieważ konwencja ma większe znaczenie niż nazwy opisowe, ale to smutne, że to najlepsze, co mogli wymyślić.
warbaker
4
@warbaker: Uważam, że to dobry sposób na odróżnienie sparametryzowanych typów od rzeczywistych klas. W jaki sposób można stwierdzić, czy w inny sposób, np Elementw List<Element>to parametryzowane typ lub klasę?
BalusC,
1
Wygląda na to, że nie BiFunction<T, U, R>przestrzega tej konwencji. Gdyby tak było, byłoby BiFunction<T, S, R>.
michaelsnowden
4
Po co martwić się rozróżnianiem typów sparametryzowanych od rzeczywistych klas? To klasy. Bez względu na wszystko, musisz przewinąć gdzieś w pliku, aby dowiedzieć się, jakie są definicje. Będzie to import lub typ sparametryzowany.
Vectorjohn,
47

Dodać Type

Dobre omówienie można znaleźć w komentarzach na stronie DZone, Konwencje nazewnictwa dla typów parametryzowanych .

Zobacz komentarz Erwina Muellera. Jego sugestia ma dla mnie całkowicieType oczywisty sens: Dołącz słowo .

Nazwij jabłko jabłkiem, samochód samochodem. Nazwa, o której mowa, to nazwa typu danych, prawda? (W OOP klasa zasadniczo definiuje nowy typ danych.) Nazwijmy to „Typem”.

Przykład Muellera zaczerpnięty z artykułu w oryginalnym poście:

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

Dodać T

Duplikat pytania zawiera tę odpowiedź autorstwa Andy'ego Thomasa. Zwróć uwagę na fragment przewodnika stylistycznego Google, który sugeruje, że wieloznakowa nazwa typu powinna kończyć się jedną wielką literą T.

Basil Bourque
źródło
3
Podoba mi się ta odpowiedź. Dodanie „Typu” jest bardzo przejrzyste i pozwala na uzyskanie opisowych nazw. Mam dość ludzi, którzy mówią: „rób to, bo taka jest konwencja”, bez żadnego innego uzasadnienia. Jeśli to zła konwencja, może potrzebujemy nowej.
Drew
16

Powód, dla którego oficjalna konwencja nazewnictwa zaleca używanie pojedynczej litery, jest następujący:

Bez tej konwencji trudno byłoby odróżnić zmienną typu od zwykłej nazwy klasy lub interfejsu.

Myślę, że w przypadku nowoczesnych IDE ten powód nie jest już ważny, ponieważ np. IntelliJ Idea pokazuje ogólne parametry typu w innych kolorach niż zwykłe klasy.

Kod z typem ogólnym, jak wyświetlany w IntelliJ Idea 2016.1 Kod z typem ogólnym, jak wyświetlany w IntelliJ Idea 2016.1

Z powodu tego rozróżnienia używam dłuższych nazw opisowych dla moich typów ogólnych, z taką samą konwencją, jak w typach regularnych. Unikam dodawania przedrostków i przyrostków, takich jak T lub Type, ponieważ uważam je za niepotrzebny szum i nie są już potrzebne do wizualnego rozróżniania typów ogólnych.

Uwaga: ponieważ nie jestem użytkownikiem Eclipse ani Netbeans, nie wiem, czy oferują one podobną funkcję.

Vojtech Ruzicka
źródło
Nie oparłbym konwencji nazewnictwa na założonych możliwościach narzędzi, które każda osoba kiedykolwiek czytała / modyfikowała ten sam plik. Osobiście lubię używać edytora tekstu do mojego kodowania (Sublime Text), który nie jest IDE. W dzisiejszych czasach edytory tekstu zwykle mają kolorowanie składni, ale nie mają głębokiego zrozumienia podstawowej struktury kodu, która moim zdaniem byłaby wymagana do poprawnego pokolorowania nazw zmiennych. A oparcie tego argumentu na kolorze jest z natury wyłączne dla osób ze słabym widzeniem kolorów (należę do 8% mężczyzn z ślepotą barw czerwono-zieloną)
joonas.fi
1
Dobra uwaga w przypadku osób ze słabym widzeniem kolorów. Jeśli chodzi o niestosowanie IDE - jeśli ludzie wolą używać prostych edytorów tekstu, to jest w porządku, ale dobrowolnie rezygnują z funkcji oferowanych przez IDE na rzecz lżejszego narzędzia. Może to być tylko jedna z brakujących funkcji. Ostatecznie jednak, jeśli zamiast pojedynczej litery używana jest nazwa opisowa, powinieneś być w stanie określić znaczenie na podstawie nazwy bez IDE i bez kodowania kolorami. Kodowanie kolorami po prostu przyspiesza to.
Vojtech Ruzicka
16

Tak, można używać nazw wieloznakowych dla zmiennych typu, o ile są one wyraźnie odróżniane od nazw klas.

Różni się to od konwencji sugerowanej przez Sun przy wprowadzeniu leków generycznych w 2004 roku. Jednak:

  • Istnieje więcej niż jedna konwencja.
  • Nazwy wieloznakowe są zgodne z innymi stylami Java, na przykład stylem Google dla języka Java .
  • Czytelne nazwy są (niespodzianka!) Bardziej czytelne.

Czytelność

W niektórych interfejsach, które napisałem, chciałbym nazwać parametr typu generycznego więcej niż jednym znakiem, aby kod był bardziej czytelny.

Czytelność jest dobra.

Porównać:

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

do:

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

lub zgodnie z konwencją wieloznakową 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> {

Styl Google

Przewodnik po stylach języka Java Google dopuszcza zarówno nazwy jednoliterowe, jak i wieloznakowe nazwy klasowe kończące się na T.

5.2.8 Wpisz nazwy zmiennych

Każda zmienna typu ma nazwę w jednym z dwóch stylów:

  • Pojedyncze litery, a następnie ewentualnie przez jeden cyfrze (na przykład E, T, X, T2)

  • Nazwa w formie stosowanej do klas (patrz punkt 5.2.2 Nazwy klas ), a następnie litery T (przykłady: RequestT, FooBarT).

Zagadnienia

„Bez tej konwencji trudno byłoby odróżnić zmienną typu od zwykłej nazwy klasy lub interfejsu”. - z samouczków Oracle, „Typy ogólne”

Nazwy jednoznakowe nie są jedynym sposobem odróżnienia parametrów typu od nazw klas, jak widzieliśmy powyżej.

Dlaczego nie udokumentować po prostu znaczenia parametru typu w JavaDoc?

Prawdą jest, że @paramelementy JavaDoc mogą zapewnić dłuższy opis. Ale prawdą jest również to, że JavaDocs niekoniecznie są widoczne. (Na przykład w Eclipse istnieje pomoc dotycząca treści, która wyświetla nazwy parametrów typu).

Nazwy parametrów typu wieloznakowego nie są zgodne z konwencją Oracle!

Wiele oryginalnych konwencji firmy Sun jest przestrzeganych prawie powszechnie w programowaniu w języku Java.

Jednak ta konkretna konwencja nie jest.

Najlepszy wybór spośród konkurencyjnych konwencji to kwestia opinii. Konsekwencje wyboru innej konwencji niż Oracle w tym przypadku są niewielkie. Ty i Twój zespół możecie wybrać konwencję, która najlepiej odpowiada Twoim potrzebom.

Andy Thomas
źródło
15

Możesz użyć javadoc, aby przynajmniej dać wskazówkę użytkownikom twojej klasy ogólnej. Nadal mi się to nie podoba (zgadzam się z @ chaper29), ale doktorzy pomagają.

na przykład,

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

}

Inną rzeczą, o której byłem znany, jest używanie mojego IDE do refaktoryzacji klasy łamiącej konwencję. Następnie pracuj nad kodem i refaktoryzuj z powrotem na pojedyncze litery. I tak mi się to ułatwia, jeśli używa się wielu parametrów typu.

Tom Carchrae
źródło
1
Powiedziałbym, że komentarze Javadoc dotyczące parametrów typu są zwykle koniecznością.
migu