Perché dovreste evitare lo scope package-private in Java
Di recente stavo discutendo nel mio progetto sul modificatore di visibilità package-private.
“Aspetta, cos’è il package-private in Java? A volte è anche chiamato default o no modifier.
Questo è quando una classe o un metodo non ha alcun modificatore. Per esempio:
class SomeObject { void doSomething() { ... }}
Ci sono più dettagli nel tutorial di Java.
Non dovrebbe essere usato a meno di ragioni molto-molto specifiche. Si può scegliere tra pubblico, privato o protetto.
Ci sono ragioni che ho sentito finora da diverse persone:
- Ma ne ho bisogno per testare il metodo nel mio oggetto!
- Ma è meglio limitare l’accesso all’oggetto il più possibile! Si accede solo alle classi dello stesso pacchetto.
- Ho una libreria con molti utenti e voglio nascondere loro i dettagli dell’implementazione!
Ma mi serve per testare i metodi nel mio oggetto!
Non fate il package-private solo per testare quel metodo molto importante. È una delle frequenti fallacie che osservo. Le persone tendono a ottenere in qualche modo l’accesso a quella logica privata, la rilassano un po’ e poi fanno test sporchi!
C’è un modo migliore. Per prima cosa dovete capire che probabilmente c’è qualcosa di sbagliato nel vostro progetto, se c’è una qualche funzionalità nascosta che è difficile da testare. Significa che è un candidato perfetto per il refactoring! Basta estrarre quella logica in una classe interna con metodi API ben definiti e testarli.
Ma è meglio limitare l’accesso all’oggetto il più possibile! Si accede solo alle classi dello stesso pacchetto.
La documentazione ufficiale Oracle dice:Use the most restrictive access level that makes sense for a particular member.
Use private unless you have a good reason not to.
Sono totalmente d’accordo con questa affermazione, solo se lasciamo perdere il package-private da questa lista. La vita sarà molto più facile per il vostro progetto se tutto sarà pubblico/privato. Uno dei refactorings più frequenti nei grandi codebases è Move File/Class
. Con un sacco di accessi privati ai pacchetti diventerà subito fastidioso farlo. Perché non renderli pubblici allora?
Alla fine sia il pubblico che il pacchetto-privato espongono l’API della vostra classe. Non importa che nel secondo caso sia limitato dal pacchetto, è ancora un’API di cui dovete preoccuparvi.
- Test. È una tendenza relativamente nuova quella di non scrivere modificatori di accesso per il codice di test. Comunque i modificatori portano un po’ di rumore al codice e la visibilità dell’accesso non è così importante nei test come lo è nel codice di produzione. Meno digitazione è meglio!
- Stai supportando una libreria con molti utenti. A meno che la tua libreria non sia compatibile con java8 o meno! Altrimenti ti incoraggio a usare JPMS (Project Jigsaw) nelle tue librerie, che ti darà un controllo molto migliore sulle tue API esposte e sull’implementazione interna rispetto al package-private
Così come puoi vedere nel 2019 (presto 2020!) non ci sono molte ragioni per andare con la visibilità package-private.