Nazewnictwo interfejsu w Javie [zamknięty]

Większość języków OO prefixuje nazwy interfejsów dużymi literami I, dlaczego Java tego nie robi? Jakie były przesłanki nieprzestrzegania tej konwencji?

Aby zademonstrować, co mam na myśli, gdybym chciał mieć interfejs użytkownika i implementację użytkownika, miałbym dwie możliwości w Javie:

  1. Class = User, Interface = UserInterface
  2. Class = UserImpl, Interface = User

Gdzie w większości języków:

Class = User, Interface = IUser

Teraz możesz twierdzić, że zawsze możesz wybrać najbardziej opisową nazwę dla implementacji użytkownika i problem znika, ale Java wypycha podejście POJO Do Rzeczy i większość kontenerów IOC używa szeroko DynamicProxies. Te dwie rzeczy razem oznaczają, że będziesz miał wiele interfejsów z pojedynczą implementacją POJO.

Moje pytanie sprowadza się więc do: " czy warto stosować się do szerszej konwencji nazewnictwa interfejsów szczególnie w świetle do czego zmierzają frameworki Javy?"

Author: mavis, 2009-02-12

11 answers

Wolę nie używać prefiksu na interfejsach:

  • Przedrostek szkodzi czytelności.

  • Używanie interfejsów w klientach jest standardowym najlepszym sposobem programowania, więc nazwy interfejsów powinny być tak krótkie i przyjemne, jak to tylko możliwe. Implementacja klas powinna być brzydsza, aby zniechęcić do ich używania.

  • Przy zmianie z klasy abstrakcyjnej na interfejs konwencja kodowania z prefiksem I zakłada zmianę nazw wszystkich wystąpień klasy - - - nie dobrze!

 298
Author: starblue,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-12 16:23:43

Czy naprawdę jest różnica między:

class User implements IUser

I

class UserImpl implements User

Jeśli mówimy tylko o konwencjach nazewniczych?

Osobiście wolę nie poprzedzać interfejsu I, ponieważ chcę być kodowany do interfejsu i uważam , że jest ważniejszy pod względem konwencji nazewnictwa. Jeśli wywołasz interfejs IUser, to każdy konsument tej klasy musi znać jego an IUser. Jeśli wywołasz klasę UserImpl to tylko klasa i twój DI kontener wie o części Impl, a konsumenci po prostu wiedzą, że pracują z User.

Z drugiej strony, czasy, w których byłem zmuszony używać Impl, ponieważ lepsza Nazwa się nie prezentuje, były nieliczne, ponieważ implementacja otrzymuje nazwę zgodnie z do implementacji, ponieważ tam jest to ważne, np.

class DbBasedAccountDAO implements AccountDAO
class InMemoryAccountDAO implements AccountDAO
 101
Author: tddmonkey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-21 13:53:23

Może być kilka powodów, dla których Java generalnie nie używa konwencji IUser.

  1. Częścią podejścia obiektowego jest to, że nie trzeba wiedzieć, czy klient używa interfejsu, czy klasy implementacyjnej. Tak więc, nawet List jest interfejsem, a String jest rzeczywistą klasą, metoda może być przekazana obu z nich - nie ma sensu wizualnie odróżniać interfejsów.

  2. Ogólnie rzecz biorąc, wolimy używać interfejsów w kod klienta (na przykład List od ArrayList). Więc nie ma sensu, aby interfejsy wyróżniały się jako wyjątki.

  3. Konwencja nazewnictwa Javy preferuje dłuższe nazwy o rzeczywistych znaczeniach niż przedrostki w stylu węgierskim. Aby Kod był jak najbardziej czytelny: lista reprezentuje listę, a użytkownik reprezentuje użytkownika-nie IUser.

 71
Author: Avi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-12 16:17:16

Istnieje również inna konwencja, używana przez wiele projektów open source, w tym Spring.

interface User {
}

class DefaultUser implements User {
}

class AnotherClassOfUser implements User {
}

Osobiście nie lubię przedrostka " I " z tego prostego powodu, że jest to opcjonalna konwencja. Czy iiopconnection oznacza interfejs dla IOPConnection? Co jeśli klasa nie ma przedrostka" I", czy wtedy wiem, że nie jest to interfejs..odpowiedź tutaj brzmi nie, ponieważ konwencje nie zawsze są przestrzegane, a ich przestrzeganie stworzy więcej pracy niż konwencja sam ratuje.

 69
Author: ng.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-12 16:15:07

Jak powiedział inny plakat, zwykle lepiej jest, aby interfejsy definiowały możliwości, a nie typy. Raczej nie" zaimplementowałbym "czegoś takiego jak" User", dlatego" IUser " często nie jest tak naprawdę potrzebny w opisany tutaj sposób. Często widzę klasy jako rzeczowniki i interfejsy jako przymiotniki:

class Number implements Comparable{...}  
class MyThread implements Runnable{...}
class SessionData implements Serializable{....}

Czasami Przymiotnik nie ma sensu, ale ogólnie używałbym interfejsów do modelowania zachowań, akcji,możliwości, właściwości itp... nie typami.

Ponadto, jeśli naprawdę zamierzałeś zrobić tylko jednego użytkownika i nazwać go użytkownikiem, to jaki jest sens posiadania interfejsu IUser? A jeśli masz zamiar mieć kilka różnych typów użytkowników, którzy muszą zaimplementować wspólny interfejs, co dodanie " I " do interfejsu oszczędza w wyborze nazw implementacji?

Myślę, że bardziej realistycznym przykładem może być to, że niektóre typy użytkowników muszą być w stanie zalogować się do określonego API. Możemy zdefiniować interfejs logowania, a potem mieć klasę nadrzędną" User " z Suclasses SuperUser, DefaultUser, AdminUser, AdministrativeContact itp., z których niektóre będą lub nie będą implementować loginu (Loginable?) interfejs w razie potrzeby.

 43
Author: nairbv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-06 19:57:18

Bob Lee powiedział kiedyś w prezentacji:

Whats the point of a interface if you mieć tylko jedną realizację.

Więc zaczynasz z jedną implementacją, czyli bez interfejsu. później decydujesz, cóż, istnieje potrzeba interfejsu tutaj, więc przekonwertować swoją klasę do interfejsu.

Wtedy staje się oczywiste: twoja oryginalna Klasa nazywała się User. Twój interfejs nazywa się teraz użytkownikiem. może masz UserProdImpl i UserTestImpl. jeśli dobrze zaprojektowana aplikacja, każda klasa (z wyjątkiem tych, które tworzą instancję użytkownika) będzie niezmieniona i nie zauważy, że nagle przechodzą przez interfejs.

Żeby było jasne - > implementacja użytkownika interfejsu UserImpl.

 35
Author: Andreas Petersson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-14 06:33:25

W C # jest to

public class AdminForumUser : UserBase, IUser

Java powiedziałaby

public class AdminForumUser extends User implements ForumUserInterface

Z tego powodu nie sądzę, aby konwencje były tak ważne w Javie dla interfejsów, ponieważ istnieje wyraźna różnica między dziedziczeniem a implementacją interfejsu. Powiedziałbym, że po prostu wybierz dowolną konwencję nazewnictwa, o ile jesteś konsekwentny i użyj czegoś, aby pokazać ludziom, że są to Interfejsy. Nie robiłam Javy od kilku lat, ale wszystkie interfejsy byłyby po prostu we własnym katalogu i to był zjazd. Nigdy nie miałem z tym problemów.

 23
Author: Matt Briggs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-12 16:26:07

Z mojego doświadczenia wynika, że konwencja "I" odnosi się do interfejsów, które mają na celu dostarczenie kontraktu klasie, szczególnie gdy interfejs sam w sobie nie jest abstrakcyjnym pojęciem klasy.

Na przykład, w Twoim przypadku, spodziewałbym się zobaczyć IUser, jeśli jedynym użytkownikiem, którego kiedykolwiek zamierzasz mieć, jest User. Jeśli planujesz mieć różne typy użytkowników - NoviceUser, ExpertUser, itd. - Spodziewałbym się zobaczyć interfejs User (i, być może, klasę AbstractUser, która implementuje pewne wspólne funkcjonalności, np. get/setName()).

Spodziewałbym się również interfejsów definiujących możliwości - Comparable, Iterable, itd. - być tak nazwanym, a nie IComparable czy IIterable.

 6
Author: David Koelle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-05 19:23:30

Zgodnie z dobrymi zasadami OO, Twój kod powinien (w miarę praktycznych/możliwych) zależeć od abstrakcji, a nie konkretnych klas. Na przykład, ogólnie lepiej jest napisać metodę taką jak Ta:

public void doSomething(Collection someStuff) {
    ...
}

Niż to:

public void doSomething(Vector someStuff) {
    ...
}

Jeśli zastosujesz się do tego pomysłu, to utrzymuję, że Twój kod będzie bardziej czytelny, jeśli nadasz interfejsom nazwy takie jak" User "i" BankAccount "(na przykład), zamiast" IUSER"," UserInterface " lub inne odmiany.

Jedyne bity kodu które powinny dbać o rzeczywiste klasy betonu są miejsca, w których klasy betonu są konstruowane. Wszystko inne powinno być napisane przy użyciu interfejsów.

Jeśli to zrobisz, to" brzydkie "konkretne nazwy klas, takie jak "UserImpl", powinny być bezpiecznie ukryte przed resztą kodu, co może wesoło działać przy użyciu "ładnych" nazw interfejsu.

 5
Author: KarstenF,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-12 22:18:41

= v = przedrostek " I " jest również używany w frameworku Wicket, gdzie szybko się do niego przyzwyczaiłem. Ogólnie rzecz biorąc, z zadowoleniem przyjmuję każdą konwencję, która skraca uciążliwe nazwy klas Java. Jest to jednak kłopotliwe, że wszystko jest Alfabetycznie ułożone pod "I" w katalogach i w Javadoc.

Praktyka kodowania Wicket jest podobna do swingu, ponieważ wiele instancji control / widget jest konstruowanych jako anonimowe klasy wewnętrzne z deklaracjami metody inline. Irytująco, różni się o 180° od huśtawki w tym Swing używa prefiksu ("J") dla klas implementujących.

Przyrostek "Impl" jest złośliwym skrótem i nie umiędzynarodawia się dobrze. Gdybyśmy tylko chodzili z "Imp", byłoby słodsze (i krótsze). "Impl" jest używany dla IOC, zwłaszcza wiosną, więc jesteśmy jakby z nim na razie. Robi się jednak trochę schizo po 3 różnych konwencjach w trzech różnych częściach jednego kodu.

 2
Author: Jym Dyer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-13 20:57:43

Czy jest to szersza konwencja nazewnictwa w jakimkolwiek realnym znaczeniu? Jestem bardziej Po Stronie C++, a nie za bardzo po stronie Javy i potomków. Ile społeczności językowych używa konwencji I?

Jeśli masz niezależną od języka standardową konwencję nazewnictwa sklepu, użyj jej. Jeśli nie, przejdź do konwencji nazewnictwa języka.

 0
Author: David Thornley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-12 17:57:25