Campi / variabili di classe. Mantieni un singolo punto di riferimento a livello di classe o passa ai singoli metodi?

3

Spesso vedo una classe in cui un valore viene iniettato in un metodo o anche in un costruttore. Tale valore viene quindi utilizzato da diversi metodi all'interno di quella classe e un riferimento viene semplicemente passato a ciascun metodo che lo richiede. A me sembra un odore di codice, anche se potrei benissimo essere un pedante.

A meno che una variabile non sia richiesta solo una volta nell'ambito di un singolo metodo, di solito avrò un campo di livello di classe che è inizializzato dal metodo che riceve il valore. Eventuali altri metodi farebbero riferimento a questo campo se necessario. Questo sembra essere molto più pulito per me.

Pensieri?

    
posta Darren Young 02.05.2012 - 17:06
fonte

3 risposte

4

I campi dovrebbero memorizzare lo stato dell'oggetto. La durata dei campi dovrebbe essere la stessa della durata dell'oggetto. Non usarli come memoria temporanea per evitare di passare valori transitori attraverso una catena di metodi.

C'è odore di codice, ma aggiungere un campo alla classe esistente non è la soluzione adeguata. Invece, calcola i metodi privati correlati in una classe separata. Quindi è possibile estrarre gli argomenti del metodo nei campi della nuova classe.

Invece di:

class A {
  int m;
  ... // other members;
  def f(x) { u = g(x); v = h(x); m = j(t1, t2); }
}

scrittura:

class F {
  int x;
  F(x) { this.x = x; } // constructor
  int f() { t1 = g(); t2 = h(); return j(t1, t2); }
}

class A {
  int m;
  ...
  f(x) { m = new F(x).f(); }
}

Questo refactoring ha l'ulteriore vantaggio di consentire a F di essere testato separatamente da A.

    
risposta data 02.05.2012 - 17:29
fonte
1

Considera la sicurezza dei thread

In Java, tutte le variabili sullo stack di thread sono isolate da altri thread. Ciò significa che se la variabile viene passata come parametro di un metodo, o è immersa in un metodo, allora è immune dalla mutazione da altri thread. (Ciò presuppone che i riferimenti condivisi non vengano modificati altrove, come sarebbe il caso se la variabile fosse immutabile come una stringa o un DateTime di Joda.)

Questo non è il caso delle variabili di campo che possono essere mutate da altri thread che condividono la stessa istanza di oggetto se la gestione appropriata non è a posto (operazioni atomiche, sincronizzazione ecc.).

Quindi, un modo comune per prevenire questo tipo di effetto collaterale è di mantenere lo stato fuori dai campi e solo sulla pila di thread.

    
risposta data 02.05.2012 - 18:15
fonte
1

È una questione di proprietà. Se la classe possiede il valore passato, o può contenere un riferimento condiviso al valore (in gran parte costante), allora l'accoppiamento aggiunto di avere la classe mantiene la propria istanza del valore ha un senso. Altrimenti, lascerei che il valore sia semplicemente un parametro passato. Riduce l'accoppiamento tra il valore e la classe, oltre ad essere più amichevole per i test unitari e l'accesso concorrente.

    
risposta data 02.05.2012 - 17:20
fonte

Leggi altre domande sui tag