Se una variabile ha getter e setter, dovrebbe essere pubblica?

20

Se ho una classe con una variabile che è privata e la classe ha getter e setter per quella variabile. Perché non rendere pubblica tale variabile?

L'unico caso in cui penso che devi usare getter e setter è se devi fare qualche operazione oltre al set o al get. Esempio:

void my_class::set_variable(int x){
   /* Some operation like updating a log */
   this->variable = x;
}

Grazie in anticipo!

    
posta Oni 31.07.2011 - 23:52
fonte

5 risposte

16

Hai mai sentito parlare di una proprietà?

Una proprietà è un campo con accessori "incorporati" (getter e setter). Java, per esempio, non ha proprietà, ma si consiglia di scrivere getter e setter su un campo privato. C # ha proprietà.

Quindi, perché abbiamo bisogno di getter e setter? Fondamentalmente abbiamo bisogno di proteggere / proteggere il campo. Ad esempio, non stai accedendo al campo in riferimento alla memoria, stai accedendo a un metodo che modificherà il campo (riferimento). Questo metodo è in grado di eseguire alcune operazioni che un utente non è disposto a conoscere ( comportamento incapsulante ), come nell'esempio. Immagina, ad esempio, che una dozzina di classi utilizzi il tuo campo pubblico e che tu debba cambiare il modo in cui viene utilizzata ... Dovresti esaminare ognuna di queste classi per cambiare il modo in cui usano il campo ... Non quindi "OOlysh".

Ma, per esempio, se hai un campo booleano chiamato morto. Dovresti pensarci due volte prima di dichiarare un setDead e isDead. Dovresti scrivere accessors leggibili dall'uomo , ad esempio kill () invece di setDead.

Tuttavia, ci sono molti framework che presumono che stai seguendo la convenzione di denominazione JavaBean (parlando di Java qui), quindi, in questi casi, dovresti dichiarare tutti i getter e setter dopo la convocazione dei nomi.

    
risposta data 01.08.2011 - 00:06
fonte
21

Questa non è l'opinione più popolare, ma non vedo molta differenza.

Gli impostori e i getter sono una cattiva idea. Ci ho pensato e sinceramente non riesco a trovare una differenza tra un setter / getter e una variabile pubblica nella pratica.

In THEORY un setter e un getter aggiungono un posto dove fare alcune azioni extra quando una variabile viene impostata / ottenuta e in teoria isolano il tuo codice dai cambiamenti.

In realtà raramente vedo setter e getter usati per aggiungere un'azione, e quando vuoi aggiungere un'azione, devi aggiungerla a TUTTI i setter o getter di una classe (come la registrazione) che dovrebbe farti pensare che dovrebbe esserci una soluzione migliore.

Per quanto riguarda l'isolare le decisioni di progettazione, se cambi una int a una lunga devi ancora cambiare setter e almeno controllare ogni linea che le accede a mano - non c'è molto isolamento lì.

Le classi mutabili dovrebbero comunque essere evitate di default, quindi aggiungere un setter dovrebbe essere l'ultima risorsa. Questo è mitigato con il modello di builder in cui un valore può essere impostato fino a quando l'oggetto si trova in uno stato desiderato, quindi la classe può diventare immutabile e i setter generano eccezioni.

Per quanto riguarda i getter - non riesco ancora a trovare una grande differenza tra un getter e una variabile finale pubblica. Il problema qui è che in entrambi i casi è un cattivo OO. Non dovresti chiedere un valore a un oggetto e operare su di esso - dovresti chiedere a un oggetto di fare un'operazione per te.

A proposito, non sto affatto sostenendo le variabili pubbliche - sto dicendo che setter e getter (e anche proprietà) sono troppo vicini alle variabili pubbliche.

Il grosso problema è semplicemente che le persone che non sono programmatori OO sono troppo tentate di usare setter e getter per creare oggetti in palle di proprietà (strutture) che vengono passati in giro e gestiti, praticamente l'opposto di come orientato agli oggetti codice funziona.

    
risposta data 01.08.2011 - 06:36
fonte
8

L'utente di getter e setter entra nel principio di incapsulamento . Questo ti permetterà di cambiare il modo in cui le cose funzionano all'interno della classe e di mantenere tutto funzionante.

Ad esempio se altri 3 oggetti chiamano foo.bar per ottenere il valore di bar e decidi di cambiare il nome della barra in modo da avere un problema nelle tue mani. Se gli oggetti chiamati foo.bar dovresti cambiare tutte le classi che hanno questo. Se si usa un setter / getter, non si ha nulla da cambiare. Un'altra possibilità è cambiare il tipo di variabile, nel qual caso basta aggiungere un codice di trasformazione al getter / setter e stai bene.

    
risposta data 31.07.2011 - 23:59
fonte
5

L'uso di getter e setter consente anche di controllare quali contenuti vengono memorizzati in una particolare variabile. Se il contenuto deve essere di un certo tipo o valore, parte del codice setter può essere quello di assicurare che il nuovo valore soddisfi questi requisiti. Se la variabile è pubblica, non è possibile garantire che questi requisiti siano soddisfatti.

Questo approccio rende anche il tuo codice più adattabile e gestibile. È molto più semplice apportare modifiche all'architettura di una classe se si dispone di funzioni che mantengono tale architettura nascosta da tutte le altre classi o funzioni che utilizzano tale classe. Il già citato cambiamento di un nome di variabile è solo una delle molte molte modifiche che sono molto più facili da fare se si hanno funzioni come getter e setter. L'idea generale è di mantenere il più privato possibile, in particolare le variabili di classe.

    
risposta data 01.08.2011 - 00:14
fonte
2

Dici "L'unico caso in cui penso che devi usare getter e setter è se devi fare qualche operazione oltre il set o il get.".

Dovresti usare getter e setter se ad un certo punto in futuro potrebbe avere bisogno di fare qualche operazione oltre al set e ottenere e non vuoi cambiare migliaia di righe di codice sorgente quando capita.

Dovresti usare getter e setter se non vuoi che qualcuno prenda l'indirizzo della variabile e lo faccia passare, con conseguenze disastrose se quella variabile può essere cambiata senza che sia stata menzionata da alcun codice sorgente, o anche dopo l'oggetto smesso di esistere più.

    
risposta data 15.05.2015 - 12:13
fonte

Leggi altre domande sui tag