Codice simile:
public Thing[] getThings(){
return things;
}
Non ha molto senso, dal momento che il tuo metodo di accesso non sta facendo altro che restituire direttamente la struttura interna dei dati. Potresti anche dichiarare Thing[] things
come public
. L'idea alla base di un metodo di accesso consiste nel creare un'interfaccia che isola i client dai cambiamenti interni e impedisce loro di manipolare la struttura dati effettiva se non in modi discreti come consentito dall'interfaccia. Come hai scoperto quando tutto il tuo codice client si è rotto, il tuo metodo di accesso non lo ha fatto - è solo un codice sprecato. Penso che molti programmatori tendano a scrivere un codice del genere perché hanno imparato da qualche parte che tutto deve essere incapsulato con i metodi di accesso - ma questo è per le ragioni che ho spiegato. Farlo solo per "seguire il modulo" quando il metodo di accesso non serve a nulla è solo rumore.
Consiglio vivamente la soluzione proposta, che soddisfa alcuni dei più importanti obiettivi dell'incapsulamento: offrire ai clienti un'interfaccia solida e discreta che li isola dai dettagli di implementazione interna della classe e non consente loro di toccare il la struttura interna dei dati si aspetta nei modi che si decide appropriati - "la legge del privilegio meno necessario". Se osservi i grandi framework OOP popolari, come CLR, STL, VCL, lo schema che hai proposto è molto diffuso, proprio per questo motivo.
Dovresti sempre farlo? Non necessariamente. Ad esempio, se hai classi di helper o di amici che sono essenzialmente un componente della tua classe di lavoratore principale e non sono "frontali", non è necessario - è un eccesso che aggiungerà un sacco di codice non necessario. E in tal caso, non utilizzerei affatto un metodo di accesso - è insensato, come spiegato. Basta dichiarare la struttura dei dati in un modo che è limitato solo alla classe principale che lo utilizza - la maggior parte dei linguaggi supporta modi per farlo - friend
, o dichiarandolo nello stesso file della classe principale dell'operatore, ecc.
L'unico lato negativo posso vedere nella tua proposta che è più lavoro da codificare (e ora dovrai ricodificare le classi del tuo consumatore - ma devi / devi fare comunque.) Ma non è proprio un aspetto negativo: devi farlo nel modo giusto, ea volte ciò richiede più lavoro.
Una delle cose che rende buono un buon programmatore è che sanno quando il lavoro extra vale la pena, e quando non lo è. A lungo termine, inserire l'extra adesso ripagherà con grandi dividendi in futuro - se non su questo progetto, poi sugli altri. Impara a codificare nel modo giusto e usa la tua testa su di esso, non solo seguendo i moduli prescritti in modo automatico.
Note that collections more complex than arrays might require the
enclosing class to implement even more than three methods just to
access the internal data structure.
Se stai esponendo un'intera struttura di dati attraverso una classe contenente, IMO devi riflettere sul motivo per cui questa classe è incapsulata, se non è semplicemente per fornire un'interfaccia più sicura - una "classe wrapper". Stai dicendo che la classe contenitiva non esiste per quello scopo, quindi forse c'è qualcosa che non va nel tuo progetto. Prendi in considerazione la possibilità di suddividere le tue lezioni in moduli più discreti e di metterli a strati.
Una classe dovrebbe avere uno scopo chiaro e discreto e fornire un'interfaccia per supportare tale funzionalità - non di più. Potresti provare a raggruppare insieme cose che non appartengono insieme. Quando lo fai, le cose si romperanno ogni volta che devi attuare un cambiamento. Più piccole e discrete sono le tue classi, più è facile cambiare le cose: Pensa a LEGO.