Preferire i membri della classe o passare argomenti tra metodi interni?

37

Supponiamo che all'interno della porzione privata di una classe esista un valore che viene utilizzato da più metodi privati. Le persone preferiscono avere questo definito come variabile membro per la classe o passarlo come argomento per ciascuno dei metodi - e perché?

Da un lato ho potuto vedere un argomento da sostenere che ridurre lo stato (cioè le variabili membro) in una classe è generalmente una buona cosa, sebbene se lo stesso valore sia usato ripetutamente nei metodi di una classe, sembra che sarebbe essere un candidato ideale per la rappresentazione come stato per la classe per rendere il codice visibilmente più pulito se non altro.

Modifica:

Per chiarire alcuni dei commenti / domande che sono stati sollevati, non sto parlando di costanti e questo non si riferisce a nessun caso particolare, ma solo a un'ipotesi di cui stavo parlando con altre persone.

Ignorando per un momento l'angolo di OOP, il caso d'uso particolare che avevo in mente era il seguente (si supponga che passi per riferimento solo per rendere il pseudocode più pulito)

int x
doSomething(x)
doAnotherThing(x)
doYetAnotherThing(x)
doSomethingElse(x)

Quindi quello che voglio dire è che c'è una variabile che è comune tra più funzioni - nel caso che avevo in mente era dovuto al concatenamento di funzioni più piccole. In un sistema OOP, se si trattasse di tutti i metodi di una classe (per esempio a causa del refactoring tramite l'estrazione di metodi da un metodo di grandi dimensioni), tale variabile potrebbe essere passata attorno a tutti o potrebbe essere un membro della classe.

    
posta geoffjentry 27.09.2011 - 23:27
fonte

6 risposte

14

Se il valore è una proprietà della classe, tienilo nella classe, altrimenti tienilo all'esterno. Non si progettano i metodi di classe: in primo luogo, si progettano prima le sue proprietà. Se non hai pensato di mettere quella proprietà all'interno della classe in primo luogo, c'è probabilmente una ragione per questo.

La cosa peggiore che puoi fare, in termini di scalabilità, è la modifica del codice per comodità. Prima o poi scoprirai che il tuo codice è gonfio e duplicato. Tuttavia devo ammettere che a volte infrango questa regola ... La convenienza è così dannatamente attraente.

    
risposta data 27.09.2011 - 23:45
fonte
12

Se non hai effettivamente bisogno di mantenere lo stato tra le invocazioni (e apparentemente non lo fai, o non poni la domanda) allora preferirei che il valore sia un argomento, piuttosto che una variabile membro, perché una rapida occhiata alla firma del metodo ti dice che usa l'argomento, mentre è un po 'più difficile capire subito quali variabili membro vengono usate dal metodo. Inoltre, non è sempre rapido determinare quali siano le variabili dei membri privati.

Quindi normalmente non sarei d'accordo sul fatto che il codice che utilizza le variabili membro sia visibilmente più pulito, ma se le firme dei metodi stanno sfuggendo di mano potrei fare un'eccezione. È una domanda interessante, ma non è qualcosa su cui si baserà comunque il progetto.

    
risposta data 27.09.2011 - 23:59
fonte
7

Grazie per avermi fatto la domanda, volevo chiedere anche questo.

Quando stavo pensando a questo, ci sono alcuni vantaggi nel perché passarlo come argomento

  • è più facile da testare > più facile da mantenere (correlato all'ultimo punto)
  • non ha effetti collaterali
  • è più facile da capire

Vedo chiaramente il tuo punto per esempio: uno sta analizzando il documento Excel (usando la libreria POI per esempio) e invece di passare l'istanza di riga a ogni metodo che deve lavorare con quella riga, l'autore ha variabile membro currentRow e lavora con esso.

Direi che dovrebbe esserci un nome per questo anti-pattern, vero? (non elencato qui )

    
risposta data 10.06.2014 - 12:37
fonte
1

Forse dovresti estrarre una nuova classe contenente tutti i metodi che condividono quel valore. Ovviamente il metodo di livello più alto sarà pubblico nella nuova classe. Potrebbe essere utile esporre questo metodo per il test.

Se hai due o più temporari che vengono sempre passati insieme, dovresti quasi certamente estrarre una nuova classe.

    
risposta data 27.09.2011 - 23:59
fonte
1

Do people prefer having this defined as a member variable for the class or passing it as an argument to each of the methods - and why?

Se capisco cosa stai chiedendo: i metodi di una classe sono per definizione riservati ai dettagli di implementazione, quindi non avrei dubbi sull'utilizzo di qualsiasi membro direttamente da qualsiasi metodo.

On one hand I could see an argument to be made that reducing state (ie member variables) in a class is generally a good thing...

Non c'è niente di sbagliato nel dichiarare un private static final per definire le costanti. Il compilatore sarà in grado di utilizzare il valore nel considerare alcune ottimizzazioni e, essendo costanti, non aggiunge realmente lo stato alla classe.

although if the same value is being repeatedly used throughout a class' methods...

Essere in grado di fare riferimento ad esso simbolicamente (ad es., BLRFL_DURATION ) e non dover aggiungere argomenti extra ai tuoi metodi renderà il tuo codice più leggibile e quindi più manutenibile.

    
risposta data 28.09.2011 - 00:09
fonte
0

se il valore non cambia, è per definizione una costante e dovrebbe essere incapsulato all'interno della classe. In tal caso, non si considera che influenzi lo stato di un oggetto. Non conosco il tuo caso, ma penso a qualcosa di simile alla trigonometria. Se si tenta di passare un argomento di tale costante, è possibile esporre il risultato all'errore se il client passa il valore sbagliato o un valore non con la stessa accuratezza prevista dal metodo.

    
risposta data 27.09.2011 - 23:46
fonte

Leggi altre domande sui tag