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


39

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

Da un lato, ho potuto vedere un argomento su cui ridurre lo stato (cioè le variabili membro) in una classe è generalmente una buona cosa, anche se se lo stesso valore viene usato ripetutamente attraverso i metodi di una classe sembra che sarebbe l'ideale candidato alla rappresentanza come stato della classe per rendere il codice visibilmente più pulito se non altro.

Modificare:

Per chiarire alcuni dei commenti / domande che sono stati sollevati, non sto parlando di costanti e questo non è relativo ad alcun caso particolare, piuttosto solo un ipotetico di cui stavo parlando con altre persone.

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

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

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


1
Come viene utilizzato questo valore? È costante? Cambia? È soggetto a cambiamenti tra le compilation?
Oded,

Quando le cose vengono automaticamente determinate per essere tutte uguali, è più facile pensare che non abbia importanza. E se avessi una funzione che necessitava di un valore regolato (x) come x-1?
JeffO,

Risposte:


15

Se il valore è una proprietà della classe, tenerlo nella classe, altrimenti tenerlo fuori. Non progettate prima i metodi della vostra classe, ma prima progettate le sue proprietà. Se non hai pensato di mettere quella proprietà all'interno della classe in primo luogo, probabilmente c'è una ragione per questo.

La cosa peggiore che puoi fare, in termini di scalabilità, è cambiare il tuo codice per praticità. 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.


1
Sono d'accordo - il design / lo scopo originale della classe dovrebbe dirti se dovrebbe essere una variabile membro o un argomento. Vale anche la pena pensare all'angolo di iniezione della dipendenza.
Martijn Verburg,

14

Se in realtà non hai bisogno di mantenere lo stato tra le invocazioni (e apparentemente non lo fai, o non faresti la domanda), preferirei che il valore fosse 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 dire subito quali variabili membro sono usate dal metodo. Inoltre, non è sempre rapido determinare a cosa servono 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 del metodo sfuggono di mano, potrei fare un'eccezione. È una domanda utile, ma non qualcosa su cui il progetto dipenderà in ogni caso.


10

Grazie per aver posto la domanda, volevo porre anche questo.

Quando ci pensavo, ci sono alcuni vantaggi nel perché passarlo come argomento

  • è più facile 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 ad esempio la libreria POI) e invece di passare l'istanza di riga a tutti i metodi che devono lavorare con quella riga, l'autore ha una variabile membro currentRowe lavora con essa.

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


Quale Anti-Pattern vuoi dire?
Vahid Ghadiri,

In breve, avere una variabile membro solo per condividere un parametro tra due (o più) chiamate di funzione ...
Betlista,

1

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

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


1

Le persone preferiscono averlo definito come variabile membro per la classe o passarlo come argomento a ciascuno dei metodi - e perché?

Se capisco cosa mi stai chiedendo: i metodi di una classe sono per definizione al corrente dei dettagli dell'implementazione, quindi non avrei dubbi sull'uso di alcun membro direttamente da qualsiasi metodo.

Da un lato ho potuto vedere un'argomentazione secondo cui ridurre lo stato (cioè le variabili membro) in una classe è generalmente una buona cosa ...

Non c'è niente di sbagliato nel dichiarare a private static finalper definire le costanti. Il compilatore sarà in grado di utilizzare il valore nel considerare alcune ottimizzazioni ed essendo costanti, non aggiungono realmente stato alla classe.

anche se se lo stesso valore viene usato ripetutamente nei metodi di una classe ...

Essere in grado di fare riferimento ad esso simbolicamente (ad es. BLRFL_DURATION) E non dover aggiungere ulteriori argomenti ai metodi renderà il codice più leggibile e quindi più gestibile.


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 influisca sullo stato di un oggetto. Non conosco il tuo caso, ma penso a qualcosa come PI in trigonometria. Se si tenta di passare un argomento di tale costante, si potrebbe esporre il risultato a un errore se il client passa un valore errato o un valore non con la stessa accuratezza dei metodi previsti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.