Nazwy mają okazję przekazać znaczenie. Dlaczego miałbyś rzucić tę szansę z Impl?
Przede wszystkim, jeśli będziesz mieć tylko jedną implementację, zrezygnuj z interfejsu. Stwarza to problem z nazewnictwem i nic nie dodaje. Co gorsza, może to powodować problemy z niespójnymi podpisami metod w interfejsach API, jeśli ty i wszyscy inni programiści nie będziecie ostrożni, aby zawsze używać tylko interfejsu.
Biorąc to pod uwagę, możemy założyć, że każdy interfejs ma lub może mieć dwie lub więcej implementacji.
Jeśli masz teraz tylko jeden i nie wiesz, w jaki sposób ten drugi może być inny, domyślnie jest dobrym początkiem.
Jeśli masz teraz dwa, nazwij każdy zgodnie z jego przeznaczeniem.
Przykład: Niedawno mieliśmy konkretny kontekst klasy (w odniesieniu do bazy danych). Zdano sobie sprawę, że musimy być w stanie reprezentować kontekst, który był offline, więc nazwa Kontekst została użyta dla nowego interfejsu (w celu zachowania kompatybilności ze starymi interfejsami API) i utworzono nową implementację OfflineContext . Ale zgadnij, na co zmieniono nazwę oryginału? Zgadza się, ContextImpl (yikes).
W takim przypadku DefaultContext prawdopodobnie będzie w porządku, a ludzie to zrozumieją, ale nie jest tak opisowy, jak mógłby być. W końcu, jeśli nie jest offline , co to jest? Więc poszliśmy z: OnlineContext .
Przypadek specjalny: użycie przedrostka „I” na interfejsach
Jedna z pozostałych odpowiedzi sugeruje użycie przedrostka I w interfejsach. Najlepiej nie musisz tego robić.
Jeśli jednak potrzebujesz zarówno interfejsu do niestandardowych implementacji, ale masz również podstawową konkretną implementację, która będzie często używana, a podstawowa nazwa jest zbyt prosta, aby zrezygnować z samego interfejsu, możesz rozważyć dodanie „I” do interfejsu (choć jest całkowicie w porządku, jeśli nadal nie jest odpowiedni dla ciebie i twojego zespołu).
Przykład: Wiele obiektów może być „EventDispatcher”. Ze względu na interfejsy API musi to być zgodne z interfejsem. Ale chcesz również podać podstawowy moduł wysyłania zdarzeń do delegowania. DefaultEventDispatcher byłoby w porządku, ale to trochę długo, a jeśli będą często widząc jego nazwę, to może wolą używać nazwy baza EventDispatcher dla konkretnej klasy i wdrożenia IEventDispatcher dla niestandardowych implementacji:
/* Option 1, traditional verbose naming: */
interface EventDispatcher { /* interface for all event dispatchers */ }
class DefaultEventDispatcher implements EventDispatcher {
/* default event dispatcher */
}
/* Option 2, "I" abbreviation because "EventDispatcher" will be a common default: */
interface IEventDispatcher { /* interface for all event dispatchers */ }
class EventDispatcher implements IEventDispatcher {
/* default event dispatcher. */
}
if you will only ever have one implementation, do away with the interface
- chyba że chcesz przetestować komponent, w którym to przypadku możesz chcieć zachować ten interfejs w celu utworzenia MockOrder, OrderStub lub podobnego.Nazewnictwo decyduję na podstawie przypadku użycia interfejsu.
Jeśli używany jest interfejs oddzielania , wybieram
Impl
implementacje.Jeśli celem interfejsu jest abstrakcja behawioralna , wówczas implementacje są nazywane zgodnie z tym, co konkretnie robią. Często dołączam do tego nazwę interfejsu. Więc jeśli interfejs zostanie wywołany
Validator
, używamFooValidator
.Uważam, że
Default
to bardzo zły wybór. Najpierw zanieczyszcza funkcje uzupełniania kodu, ponieważ nazwy zawsze zaczynają się od niego. Inną kwestią jest to, że domyślna wartość może ulec zmianie z czasem. To, co pierwsze może być domyślnym, może po pewnym czasie stać się przestarzałą funkcją. Dlatego albo zawsze zaczynasz zmieniać nazwę zajęć, gdy tylko zmienią się wartości domyślne, albo żyjesz z wprowadzającymi w błąd nazwami.źródło
Zgadzam się z odpowiedzią Nicole (szczególnie, że interfejs prawdopodobnie nie jest konieczne w większości przypadków), ale dla dobra dyskusji będę wyrzucać dodatkową alternatywę innych niż
OrderImpl
IDefaultOrder
: ukryć realizację za statycznej metody fabryki podobnegoOrders.create()
. Na przykład:Przy takim podejściu implementacją może być anonimowa klasa wewnętrzna lub klasa prywatna
Default
Impl
nazwie lub w nazwie, lub może być nazwana czymś zupełnie innym. Niezależnie od tego, który wybierzesz, dzwoniący nie musi się tym przejmować, więc zyskujesz większą elastyczność teraz i później, kiedy / jeśli zdecydujesz się go zmienić.Doskonałymi przykładami tego wzorca w praktyce są klasy
java.util.Collections
ijava.util.concurrent.Executors
narzędzia, których metody zwracają ukryte implementacje. Jak wspomina Effective Java (w punkcie 1), ten wzorzec może pomóc w zmniejszeniu „wagi koncepcyjnej” interfejsu API.źródło
Zawsze wybieram po
OrderImpl
prostu dlatego, że pokazuje się alfabetycznie zaraz poOrder
interfejsie.źródło
Możesz nazwać interfejs z prefiksem I (IWhthing), a następnie dokonać implementacji Cokolwiek.
Oficjalne konwencje kodu Java nie mówią o tego rodzaju nazewnictwie interfejsów, jednak ten rodzaj nazewnictwa ułatwia rozpoznawanie i nawigację.
źródło
Myślę, że chociaż Domyślny może mieć sens w niektórych przypadkach, bardziej pomocne byłoby opisanie implementacji. Więc jeśli interfejs jest
UserProfileDAO
wtedy twoje implementacje mogą byćUserProfileSQLDAO
lubUserProfileLDAPDAO
czy coś takiego.źródło
jeśli to możliwe, nazwij go po tym, co / jak to robi.
zwykle najgorsze podejście to nazywanie go po tym, jak ma być używany.
Jeśli ma być używany jako klasa bazowa do implementacji, możesz użyć BaseX lub AbstractX (jeśli jest abstrakcyjny (ale spróbuj zgnieść to, co robi), ponieważ jeśli nie zrobiłby nic, nie stworzyłbyś go interfejs) Jeśli zapewnia najprostszą możliwą funkcjonalność i oczekuje się, że będzie używana bezpośrednio (nie rozszerzając jej), gdy taka funkcjonalność wystarczy, możesz nazwać ją SimpleX lub BasicX.
Jeśli jest używany, chyba że zapewniona jest inna implementacja, nazwij go DefaultX
źródło
Większość tych odpowiedzi opisuje, co się dzieje, ale nie dlaczego.
Co stało się z zasadami OO? Co Impl mówi mi o klasie i jak z niej korzystać? Powinieneś martwić się zrozumieniem zwyczajów, a nie ich budowy.
Jeśli utworzę interfejs Person, czym jest PersonImpl? Bez znaczenia. Przynajmniej DefaultPerson mówi mi, że ktokolwiek go kodował, nie powinien był tworzyć interfejsu.
Interfejsy typują polimorfizm i powinny być używane jako takie.
źródło