Sto scrivendo da una prospettiva Java (per salvarmi dovendo mettere 'da una prospettiva Java' ovunque).
La progettazione accurata di un'API non riguarda solo "l'organizzazione". Molte delle classi pubbliche che scrivo sono utilizzate da molti clienti e utilizzando il modificatore di accesso più basso possibile sono libero di cambiare il funzionamento interno delle mie classi senza infrangere il loro codice (e quindi ottenere cattive telefonate ed e-mail!). / p>
tl; dr : incapsulamento / occultamento delle informazioni, puoi cambiare la tua rappresentazione e il tuo funzionamento interno senza infrangere il codice client, i campi mutabili pubblici non sono thread-safe, promuovi l'immutabilità.
Un modulo ben progettato nasconderà i suoi dati interni e i dettagli di implementazione da altri moduli e separa nettamente la sua API dalla sua implementazione. Ciò significa che la comunicazione tra i moduli avviene solo tramite le loro API e non sono consapevoli del funzionamento interno degli altri.
L'importanza di questo è che disaccoppia i moduli gli uni dagli altri permettendo loro di essere sviluppati, testati, usati, ottimizzati e modificati in isolamento e possono essere sviluppati in parallelo. Aumenta anche il riutilizzo perché i moduli che non sono strettamente accoppiati possono potenzialmente essere utilizzati in altri contesti.
Nel libro di Joshua Bloch "Effective Java" afferma che la regola generale è:
make each class or member as inaccessible as possible. In other words, use the lowest possible access level consistent with the proper functioning of the software that you are writing.
Dopo aver progettato la tua API pubblica, il tuo istinto dovrebbe essere quello di rendere tutto il resto privato, e solo se un'altra classe nello stesso pacchetto ha davvero bisogno di accedere a un membro se lo rendi privato di un pacchetto (rimuovi il modificatore). La necessità di membri protetti in una classe pubblica dovrebbe essere relativamente rara in quanto un membro protetto diventa parte dell'API esportata della classe.
Quando hai tutto come pubblico significa che i campi di dati della classe sono accessibili direttamente e non puoi cambiare la loro rappresentazione senza cambiare l'API. Inoltre, generalmente non è possibile modificare il funzionamento interno della classe in quanto è potenzialmente in grado di infrangere il codice di chiunque stia utilizzando la classe. Questo problema / rischio viene moltiplicato per il numero dei tuoi clienti in quanto la tua classe può essere utilizzata in tutto il luogo.
Se un campo non è definitivo o è un riferimento finale a un oggetto mutabile (ad es. Data) ed è public
, si rinuncia alla capacità di limitare ciò che è memorizzato nel campo o applicare invarianti sul campo. Pertanto, se si desidera limitare un int
a un determinato intervallo di valori, se il campo public
significa che non si ha più il controllo su ciò che è memorizzato nel campo. Inoltre, perdi la capacità di intraprendere qualsiasi azione quando un campo viene modificato, il che significa che le classi con campi mutabili pubblici non sono thread-safe .
I campi
Public final
con un oggetto mutabile contengono anche tutti gli svantaggi di un campo non finale. Anche se non puoi modificare il riferimento all'oggetto, l'oggetto può comunque essere modificato, il che può rompere i meccanismi interni della tua classe e avere risultati non intenzionali e disastrosi.
Rendendo i campi privati anche minimizzi la mutabilità della tua classe. Le classi immutabili sono generalmente più facili da progettare, implementare e utilizzare rispetto a quelle mutabili. I campi privati impediscono ai client della tua classe di ottenere l'accesso a oggetti mutabili e di modificare direttamente gli oggetti. In genere, non dai mai ai client nemmeno i riferimenti agli oggetti mutabili (dai loro copie).
Mentre la tua classe riduce al minimo la mutabilità o diventa completamente immutabile diventa anche intrinsecamente thread-safe e non richiede sincronizzazione. Non possono essere corrotti da più thread che li accedono contemporaneamente. Un enorme guadagno funzionale di immutabilità è uno dei modi più semplici per ottenere la sicurezza dei thread.