Le variabili globali non sono mai necessarie a meno che tu non stia interagendo con il codice esistente che impone vincoli inadatti.
Un'alternativa è rendere esplicita la dipendenza:
1. Crea una classe che descriva lo scopo di questi dati condivisi. Senza conoscere il dominio del problema, lo chiamerò Counter
.
class Counter {
private int value = 0;
public void incrementBy(int x) {
if (x < 0)
throw IllegalArgumentException("must increment by non-negative value");
value += x;
}
public int get() { return value; }
}
Si noti che avvolgere la variabile attraverso le funzioni di accesso ci consente di imporre controlli e vincoli. Questa mancanza di controlli è uno dei problemi principali nell'esporre le variabili direttamente.
2. Utilizza un meccanismo di iniezione dipendente per fornire un'istanza Counter
a tutte le classi che ne hanno bisogno. Ad esempio, possiamo utilizzare l'iniezione del costruttore:
public class ClassName2 {
private Counter counter;
public ClassName2(Counter counter) {
this.counter = counter;
}
public void meth(){
counter.incrementBy(4);
}
}
Il contatore viene creato in un codice di inizializzazione (come la tua funzione main ()) e poi fornito quando le classi dipendenti sono istanziate:
Counter counter = new Counter();
ClassName instance = new ClassName(counter);
ClassName2 instance2 = new ClassName2(counter);
Tutte le variabili globali hanno un'istanza simile, ma sono eseguite in modo implicito durante il caricamento della classe. Gestendo da soli l'inizializzazione otteniamo molta flessibilità:
- possiamo fornire una classe Counter diversa durante il test.
- siamo in grado di utilizzare più istanze di Counter se non si suppone che parti diverse del codice condividano un contatore, ad esempio quando la funzionalità
ClassName
originale viene riutilizzata in un contesto diverso.
Se non puoi rendere esplicite queste dipendenze, almeno incapsula la variabile usando metodi statici in modo simile.