Dlaczego powinieneś unikać package-private scope w Javie
Ostatnio dyskutowałem w moim projekcie o modyfikatorze widoczności package-private.
„Zaraz, co to jest package-private w Javie?”. Jest to również czasami nazywane domyślnym lub bez modyfikatora.
Jest to sytuacja, gdy klasa lub metoda nie posiada żadnego modyfikatora. Na przykład:
class SomeObject { void doSomething() { ... }}
Więcej szczegółów znajdziesz w samouczku Java.
Nie powinno się go używać, chyba że z bardzo konkretnego powodu. Możesz wybrać pomiędzy public, private lub protected.
Są powody, które do tej pory słyszałem od różnych ludzi:
- Ale potrzebuję tego do testowania metod w moim obiekcie!
- Ale lepiej ograniczyć dostęp do obiektu tak bardzo jak to możliwe! Dostęp do niego będą miały tylko klasy z tego samego pakietu.
- Mam bibliotekę z wieloma użytkownikami i chcę ukryć przed nimi szczegóły implementacji!
Ale potrzebuję tego do testowania metody w moim obiekcie!
Nie rób package-private tylko po to, aby przetestować tą bardzo ważną metodę. Jest to jeden z częstych błędów, które obserwuję. Ludzie mają tendencję do uzyskiwania w jakiś sposób dostępu do tej prywatnej logiki, po prostu trochę ją rozluźniają, a potem robią brudne testy!
Jest lepszy sposób. Po pierwsze musisz zrozumieć, że coś prawdopodobnie jest nie tak z twoim projektem, jeśli istnieje jakaś ukryta funkcjonalność, którą trudno jest dostać do testów. Oznacza to, że jest to idealny kandydat do refaktoryzacji! Po prostu wyodrębnij tę logikę do wewnętrznej klasy z dobrze zdefiniowanymi metodami API i przetestuj je.
Ale lepiej jest ograniczyć dostęp do obiektu tak bardzo jak to tylko możliwe! Dostęp do niego mają tylko klasy o tym samym pakiecie.
Oficjalna dokumentacja Oracle mówi:Use the most restrictive access level that makes sense for a particular member.
Use private unless you have a good reason not to.
Zupełnie zgadzam się z tym stwierdzeniem, tylko jeśli usuniemy package-private z tej listy. Życie będzie o wiele łatwiejsze dla twojego projektu, jeśli wszystko będzie publiczne/prywatne. Jednym z najczęstszych refaktoryzacji w dużych bazach kodowych jest Move File/Class
. Przy dużej ilości pakietów z dostępem prywatnym stanie się to natychmiast irytujące. Dlaczego więc nie uczynić ich publicznymi?
Na końcu zarówno publiczne, jak i pakietowo-prywatne eksponują API twojej klasy. Nie ważne, że w tym drugim przypadku jest ono ograniczone przez pakiet, to wciąż jest to API, o które musisz dbać.
- Testy. Jest to stosunkowo nowy trend, aby nie pisać modyfikatorów dostępu do kodu testowego. Tak czy inaczej modyfikatory wnoszą trochę szumu do kodu, a widoczność dostępu nie ma tak dużego znaczenia w testach jak w kodzie produkcyjnym. Mniej pisania jest lepsze!
- Wspierasz bibliotekę z dużą ilością użytkowników. Chyba, że Twoja biblioteka powinna być kompatybilna z java8 lub mniej! W przeciwnym razie zachęcam do korzystania z JPMS (Project Jigsaw) w swoich libach, co da ci znacznie lepszą kontrolę nad eksponowanymi API i wewnętrzną implementacją w porównaniu do package-private
Jak więc widać w 2019 (wkrótce 2020!) roku nie ma tak wielu powodów, aby przejść z widocznością package-private.