No.
I getter ei setter non incapsulano violano , forniscono . Se stai usando metodi accessor, sei non per definizione che accede direttamente alle variabili di un oggetto. Stai invece utilizzando un'interfaccia che l'oggetto fornisce per manipolare alcune proprietà, e non ti importa se quelle proprietà sono memorizzate in ivars, memorizzate in un dizionario, calcolate da altri valori, ecc. L'implementatore della classe in questione rimane libero per cambiare il modo in cui la classe funziona senza rompere il codice client esistente fintanto che mantiene l'interfaccia.
Alcuni dicono che se la tua interfaccia consiste di poco più di un set di accessor per le tue variabili di istanza, la tua classe non sta facendo abbastanza per giustificare la sua esistenza, o non stai facendo abbastanza per nascondere il modo in cui la classe lavora codice esterno. Tutto ciò può essere vero, a seconda della classe, ma non cambia il fatto che l'accesso allo stato interno (gli ivar) è limitato ai metodi propri della classe e quindi incapsulato.
C'è ovviamente qualche disaccordo nei commenti qui sotto su cosa significhi il termine incapsulazione . Offro la seguente definizione dal documento Encapsulation and Inheritance in Linguaggi di programmazione orientati agli oggetti ( pdf ):
A module is encapsulated if clients are restricted by the definition
of the programming language to access the module only via its defined
external interface. Encapsulation thus assures designers that
compatible changes can be made safely, which facilitates program
evolution and maintenance. These benefits are especially important for
large systems and long-lived data.
È difficile sostenere che gli accessor non si qualificano come "interfaccia esterna definita" per una classe. Se prendi anche misure per impedire l'accesso diretto esterno allo stato interno di una classe (cioè, rendi i tuoi ivars "privati"), allora con la definizione sopra avrai ottenuto l'incapsulamento.
Da un punto di vista pragmatico, tuttavia, le cose non sono esattamente così semplici. Il paragrafo successivo del documento continua a dire:
To maximize the advantages of encapsulation, one should minimize the
exposure of implementation details in external interfaces. A
programming language supports encapsulation to the degree that it
allows minimal external interfaces to be defined and enforced.
Come ogni tecnica, l'incapsulamento può essere usato bene o non così bene, e penso che questo sia al centro della maggior parte delle divergenze di opinione su ciò che fa o non "spezza" l'incapsulamento. Se nascondere la rappresentazione interna dei dati dietro un'interfaccia esterna è un bene, allora è meglio rivelare solo ciò che è necessario affinché la classe faccia il suo lavoro. Una classe che abbia una corrispondenza uno-a-uno tra gli accessor e gli ivars della proprietà può essere propriamente detta per incapsulare il suo stato, ma potrebbe non usare tale incapsulamento al meglio. Sono d'accordo che se il tuo codice contiene molte classi in questa situazione, è una buona scommessa che il sistema non sia così ben progettato come potrebbe essere.
Come puoi giudicare se stai usando l'incapsulamento in modo efficace? Continuando dal foglio:
This support can be characterized by the kinds of changes that can
safely be made to the implementation of a module. For example, one
characteristic of an object-oriented language is whether it permits a
designer to define a class such that its instance variables can be
renamed without affecting clients.
Mi piace questo test perché fornisce una semplice linea guida che corrisponde direttamente al motivo per cui valutiamo l'incapsulamento in primo luogo. Inoltre chiarisce l'idea che il vantaggio ottenuto dall'incapsulazione è un valore continuo, non binario. Non dovremmo perdere di vista il fatto che il documento descrive l'incapsulamento come una caratteristica del linguaggio, ma penso che sia sicuro applicare il test a un codice specifico per aiutarci a decidere quanto bene quel codice utilizza l'incapsulamento fornito dalla lingua.
Esempio 1: Applicazione del "Che tipo di modifiche possono essere apportate in modo sicuro?" testare l'esempio nella domanda dell'OP, sembra probabile che il codice probabilmente non faccia buon uso dell'incapsulamento. Potrebbe essere tecnicamente vero che i metodi get_byte_buffer_length()
e set_byte_buffer_length()
incapsulino qualche stato interno, ma se il "byte buffer" è un dettaglio di implementazione piuttosto che un'importante proprietà esterna del server UDP, il buffer non dovrebbe essere esposto a tutti. Il fatto stesso che sia esposto limita i modi in cui il server UDP può essere modificato.
Esempio 2: Spesso si dice che l'ereditarietà rompe l'incapsulamento perché le sottoclassi tipicamente (a seconda della lingua) hanno accesso diretto allo stato interno della classe genitrice. Ciononostante, i programmatori possono sfruttare l'incapsulamento utilizzando accessor (a volte accessor privati) per accedere allo stato da una classe genitore invece di utilizzare lo stesso ivar.
In caso di dubbio, un programmatore dovrebbe chiedersi: Il mio codice si interromperà se la classe genitore cambia? e Sottoclassi di questa interruzione di classe se cambio X?