Większość języków OO poprzedza swoje nazwy interfejsów wielką literą I, dlaczego Java tego nie robi? Jakie było uzasadnienie 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:
- Klasa = Użytkownik, Interfejs = Interfejs użytkownika
- Klasa = UserImpl, Interfejs = Użytkownik
Gdzie w większości języków:
Klasa = Użytkownik, Interfejs = Użytkownik
Teraz możesz argumentować, że zawsze możesz wybrać najbardziej opisową nazwę dla implementacji użytkownika, a problem zniknie, ale Java popycha podejście POJO do rzeczy, a większość kontenerów IOC intensywnie korzysta z DynamicProxies. Te dwie rzeczy razem oznaczają, że będziesz mieć wiele interfejsów z jedną implementacją POJO.
Wydaje mi się, że moje pytanie sprowadza się do: „Czy warto stosować szerszą konwencję nazewnictwa interfejsów, zwłaszcza w świetle tego, dokąd zmierzają frameworki Java?”
źródło
NetworkInterface
,DialogInterface
itpOdpowiedzi:
Wolę nie używać prefiksu na interfejsach:
Prefiks szkodzi czytelności.
Używanie interfejsów w klientach jest standardowym najlepszym sposobem programowania, dlatego nazwy interfejsów powinny być możliwie krótkie i przyjemne. Wdrażanie klas powinno być brzydsze, aby zniechęcić do ich używania.
Przy zmianie klasy abstrakcyjnej na interfejs konwencja kodowania z prefiksem I implikuje zmianę nazwy wszystkich wystąpień klasy --- niedobrze!
źródło
Czy naprawdę jest różnica między:
i
jeśli wszystko, o czym mówimy, to konwencje nazewnictwa?
Osobiście wolę NIE poprzedzać interfejsu,
I
ponieważ chcę kodować do interfejsu i uważam, że jest to ważniejsze z punktu widzenia konwencji nazewnictwa. Jeśli wywołasz interfejs,IUser
każdy konsument tej klasy musi znać jego interfejsIUser
. Jeśli zadzwonisz do klasy,UserImpl
tylko klasa i twój kontener DI wiedzą o tejImpl
części, a konsumenci po prostu wiedzą, że pracują zUser
.Z drugiej strony czasy, których zmuszono mnie użyć,
Impl
ponieważ lepsza nazwa się nie przedstawia, były rzadkie, ponieważ implementacja jest nazywana zgodnie z implementacją, ponieważ jest to ważne, np.źródło
Może być kilka powodów, dla których Java zasadniczo nie korzysta z konwencji IUser.
Częścią podejścia zorientowanego obiektowo jest to, że nie powinieneś wiedzieć, czy klient używa interfejsu czy klasy implementacji. Tak więc, nawet List jest interfejsem, a String jest rzeczywistą klasą, do obu metod można przekazać metodę - nie ma sensu wizualnie rozróżniać interfejsów.
Ogólnie rzecz biorąc, wolimy używać interfejsów w kodzie klienta (na przykład wolą List od ArrayList). Dlatego nie ma sensu, aby interfejsy wyróżniały się jako wyjątki.
Konwencja nazewnictwa Java preferuje dłuższe nazwy o rzeczywistych znaczeniach od prefiksów w stylu węgierskim. Aby ten kod był jak najbardziej czytelny: Lista reprezentuje listę, a Użytkownik reprezentuje użytkownika - nie użytkownika IUser.
źródło
Istnieje również inna konwencja, z której korzysta wiele projektów open source, w tym Spring.
Osobiście nie podoba mi się prefiks „ja” z tego prostego powodu, że jest to opcjonalna konwencja. Jeśli więc to zrobię, czy IIOPConnection oznacza interfejs dla IOPConnection? Co jeśli klasa nie ma przedrostka „ja”, to czy wiem, że nie jest to interfejs… odpowiedź tutaj brzmi „nie”, ponieważ konwencje nie zawsze są przestrzegane, a ich przestrzeganie spowoduje więcej pracy niż sama konwencja.
źródło
Jak powiedział inny plakat, zwykle lepiej jest, aby interfejsy definiowały możliwości, a nie typy. Nie chciałbym „implementować” czegoś takiego jak „Użytkownik” i dlatego „IUser” często nie jest tak naprawdę potrzebny w opisany tutaj sposób. Często widzę klasy jako rzeczowniki, a interfejsy jako przymiotniki:
Czasami przymiotnik nie ma sensu, ale nadal ogólnie używam interfejsów do modelowania zachowania, działań, możliwości, właściwości itp., A nie typów.
Ponadto, jeśli naprawdę chciałbyś stworzyć tylko jednego Użytkownika i nazwać go Użytkownikiem, to po co mieć interfejs IUser? A jeśli masz mieć kilka różnych typów użytkowników, którzy muszą wdrożyć wspólny interfejs, co dodanie „I” do interfejsu oszczędza ci przy wyborze nazw implementacji?
Wydaje mi się, że bardziej realistycznym przykładem jest to, że niektóre typy użytkowników muszą mieć możliwość zalogowania się do określonego interfejsu API. Moglibyśmy zdefiniować interfejs logowania, a następnie mieć klasę nadrzędną „Użytkownik” z sukkulami SuperUser, DefaultUser, AdminUser, AdministrativeContact itp., Z których niektóre będą, lub nie, w razie potrzeby implementować interfejs logowania (do zalogowania?).
źródło
indefinite transitive verbs
8 ^ PBob Lee powiedział kiedyś w prezentacji:
więc zaczynasz od jednej implementacji, tj. bez interfejsu. później decydujesz, no cóż, potrzebny jest tutaj interfejs, więc przekonwertuj klasę na interfejs.
wtedy staje się oczywiste: twoja oryginalna klasa nazywała się Użytkownik. Twój interfejs nazywa się teraz Użytkownik. może masz UserProdImpl i UserTestImpl. jeśli dobrze zaprojektowałeś aplikację, każda klasa (z wyjątkiem tych, które tworzą użytkownika) pozostanie niezmieniona i nie zauważy, że nagle przejdzie interfejs.
więc staje się jasne -> Interfejs Implementacja użytkownika UserImpl.
źródło
W języku C # jest
Java powiedziałaby
Z tego powodu nie uważam, że konwencje są tak samo 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 chcesz, o ile jesteś konsekwentny i użyj czegoś, aby pokazać ludziom, że są to interfejsy. Nie robiłem java od kilku lat, ale wszystkie interfejsy będą po prostu w swoim katalogu i taka była konwencja. Nigdy tak naprawdę nie miałem z tym żadnych problemów.
źródło
Z mojego doświadczenia wynika, że konwencja „ja” ma zastosowanie do interfejsów, które mają na celu zapewnienie kontraktu z klasą, szczególnie gdy sam interfejs nie jest abstrakcyjnym pojęciem klasy.
Na przykład w twoim przypadku spodziewam się tylko,
IUser
czy jedynym użytkownikiem, który kiedykolwiek zamierzasz mieć, jestUser
. Jeśli planujesz mieć różne typy użytkowników -NoviceUser
,ExpertUser
itp. - Spodziewałbym sięUser
interfejsu (i być możeAbstractUser
klasy, która implementuje niektóre typowe funkcje, takie jakget/setName()
).Chciałbym również spodziewać interfejsy, które definiują możliwości -
Comparable
,Iterable
itp - być nazwany tak, a nie jakIComparable
alboIIterable
.źródło
Zgodnie z dobrymi zasadami OO, twój kod powinien (o ile to praktyczne / możliwe) zależeć od abstrakcji, a nie od konkretnych klas. Na przykład ogólnie lepiej jest napisać taką metodę:
od tego:
Jeśli zastosujesz się do tego pomysłu, utrzymuję, że twój kod będzie bardziej czytelny, jeśli podasz interfejsy takie jak „Użytkownik” i „Konto bankowe” (na przykład), a nie „IUser”, „Interfejs użytkownika” lub inne odmiany.
Jedynymi fragmentami kodu, które powinny zwracać uwagę na faktyczne konkretne klasy, są miejsca, w których budowane są konkretne klasy. Cała reszta powinna być napisana za pomocą interfejsów.
Jeśli to zrobisz, wówczas „brzydkie” konkretne nazwy klas, takie jak „UserImpl”, powinny być bezpiecznie ukryte przed resztą kodu, co można wesoło kontynuować przy użyciu „ładnych” nazw interfejsów.
źródło
= v = Prefiks „I” jest także używany w frameworku Wicket, do którego szybko się przyzwyczaiłem. Ogólnie rzecz biorąc, z zadowoleniem przyjmuję każdą konwencję, która skraca nieporęczne nazwy klas Java. Problemem jest jednak to, że wszystko jest uporządkowane alfabetycznie pod „I” w katalogach i Javadoc.
Praktyka kodowania furtek jest podobna do Swinga, ponieważ wiele instancji sterujących / widgetów jest zbudowanych jako anonimowe klasy wewnętrzne z deklaracjami metod wbudowanych. Irytujące, różni się o 180 ° od Swing tym, że Swing używa przedrostka („J”) dla klas implementujących.
Przyrostek „Impl” jest złośliwym skrótem i nie jest dobrze umiędzynarodowiony. Gdybyśmy przynajmniej wybrali „Imp”, byłby ładniejszy (i krótszy). „Impl” jest używane w MKOl, szczególnie Spring, więc na razie utknęliśmy z tym. Jednak robi się trochę schizo po 3 różnych konwencjach w trzech różnych częściach jednej bazy kodu.
źródło
Czy jest to szersza konwencja nazewnictwa w jakimkolwiek realnym sensie? Jestem bardziej po stronie C ++, a tak naprawdę nie lubię Java i potomków. Ile społeczności językowych korzysta z konwencji I?
Jeśli masz tutaj standardową konwencję nazewnictwa sklepu niezależną od języka, skorzystaj z niej. Jeśli nie, przejdź do konwencji nazewnictwa języków.
źródło