Come viene interrotto l'incapsulamento da getter / setter, anche quando si utilizza il modello MVC [duplicato]

3

Stavo pensando all'incapsulamento in Java e poi ho pensato a come i getter / setter rompono l'incapsulamento. Dopo aver esaminato questo , ho visto molte raccomandazioni come evitare i getter / setter su campi non necessari o alcune politiche su come implementarli.

Quello che non sono riuscito a capire è nel caso di un modello MVC, in che modo i getter / setter interrompono l'incapsulamento. Incase se qualcuno vuole prendere un esempio di framework MVC, vorrei prendere in considerazione Spring-MVC.

Quindi, in pratica, in MVC i dati sono manipolati generalmente dal codice aziendale, implementando un'interfaccia. Il codice aziendale sta ricevendo ordini da Controller, che non sta affatto scherzando con Model.

In questo modo, vedo che il modello è ben isolato o sepolto tra due livelli: Controller e Business. Qualcuno può spiegarmi perché anche in un modello MVC i getter e gli incastonatori rompono l'incapsulamento.

Spero che la mia domanda sia stata chiara. Se manca qualcosa, cortesemente fammi sapere. Grazie.

Modifica

Forse le persone non stanno leggendo ma stanno semplicemente girovagando. La mia domanda riguarda principalmente MVC e incapsulamento piuttosto che perché i getter / setter sono giustificati. Il mio punto di riferimento rimane ancora su MVC, ecco perché non ho accettato la risposta.

    
posta We are Borg 17.09.2015 - 14:06
fonte

2 risposte

5

Risposta rapida: l'utilizzo dei metodi getter e setter nel modo in cui descrivi molto probabilmente andrà bene. E rimuoverli non risolverà alcun problema concreto.

Risposta più lunga

Ricorda che l'incapsulamento riguarda nascondere le informazioni . Formalmente, quello che vuoi è una struttura dati - i tuoi campi privati - che è solo mai accessibile e modificato tramite un set fisso di routine - i tuoi metodi. Ciò migliora la manutenzione, perché se si desidera modificare la struttura dei dati interna, è sufficiente passare attraverso il set di routine finito per effettuare l'aggiornamento, piuttosto che l'intero programma. È facile vedere il vantaggio :).

Il problema in get / set viene quando esponi informazioni sull'implementazione . Prendiamo l'esempio dell'esposizione di una connessione al database. All'improvviso, hai dichiarato al mondo che il tuo oggetto parla con un database. Il codice client utilizzerà quella connessione per fare altre cose. 2 anni dopo, rimuovi il database, non è più necessario. Ma il codice client si aspetta una connessione al vecchio database! Non puoi cambiare il tuo oggetto nel modo desiderato e devi portare in giro cianfrusaglie inutili ... hai esposto dettagli che non dovresti!

In un altro caso, però, non hai nulla da nascondere: un cliente è un ID, un nome e un numero di telefono. Non nasconderlo, è proprio ciò di cui ha bisogno il codice cliente! Molteplici parti dell'applicazione richiedono questo per fare il loro lavoro: l'interfaccia utente visualizzerà una versione formattata per l'utente, il database salverà e leggerà il valore, una libreria JSON serializzerà le informazioni per inviare un ordine a una terza parte. Questa è informazioni commerciali . Deve essere accessibile per essere utile. In tal caso, un getter - e forse un setter - è perfettamente valido.

Nel tuo caso: se il getter nella tua logica aziendale nasconde il tuo modello, è perfettamente a posto. Usali. Un design getter-less non può essere migliore.

Come nota finale: le persone sono spesso contro getter a causa di qualcosa chiamato "tell do not ask". Questo è un problema completamente diverso dall'incapsulamento. È una filosofia di design, e i benefici sono meno chiari che con l'occultamento delle informazioni. Quest'ultimo era già noto negli anni '70, mentre il primo è un'invenzione più recente. "Dillo non chiedere" è meraviglioso per alcune applicazioni, in particolare quelle basate sugli eventi. Purtroppo, funziona male con le applicazioni CRUD, dove l'intero punto è chiedere informazioni. Supponendo che tu esca dallo specifico insieme di problemi che "tell do not ask" risolve, usa getter senza alcun senso di colpa. Ricorda solo di nascondere la tua implementazione .

    
risposta data 17.09.2015 - 16:58
fonte
2

È dovuto al fatto che un getter / setter espone gli stessi dati di una variabile pubblica, dato che sono semplicemente call wrapper di metodo attorno alla variabile.

Una volta che le persone si rendevano conto che le variabili pubbliche erano una cattiva idea, potevano essere modificate esternamente all'oggetto senza costrizione. La soluzione consiste nel rendere private tutte le variabili membro e introdurre metodi che agiscano su di esse per consentire un maggiore controllo e per esporre un'interfaccia che abbia senso in termini di ciò che la classe è stata progettata per fare (cioè non come lo fa).

Ma sfortunatamente, lo zucchero sintattico delle proprietà è stato introdotto per fudge la distinzione - così ora abbiamo metodi che consentono l'accesso alle variabili che fingono di essere parte dell'interfaccia di classe, quando non sono nient'altro che equivalenti al metodo di accesso alle variabili pubbliche.

Per un esempio, immagina una classe Persona che mantenga la tua età. Puoi impostarlo in una variabile membro e consentire a un chiamante di impostare p.age = 20; se si tratta di una variabile pubblica. Oppure, potresti avere una proprietà e diventa invece p.age_set(20); (effettivamente, so che lo zucchero sintattico è lì per farlo sembrare un compito variabile). Oppure potresti avere un p.Age(20); che calcola un anno di nascita e lo memorizza in una variabile, ignorando qualsiasi variabile membro age .

Quest'ultimo sta mantenendo l'incapsulamento - il chiamante non lo sa, o si cura di come l'oggetto persona tiene traccia della tua età, solo che ci sono modi per impostare e recuperare i dati. È la differenza tra la progettazione di una struct e una classe (o la progettazione basata sui dati rispetto a quella basata sul comportamento: quest'ultima è di gran lunga migliore per la manutenzione e l'utilizzo del sistema)

    
risposta data 17.09.2015 - 14:31
fonte