Sembra che tu abbia un equivoco che sta portando alla tua confusione.
However, protected variable is just a global variable (although limited) and should be avoided at all.
Un campo protected
in una classe ne limita la visibilità alla classe, altre classi nello stesso pacchetto e sottoclassi. Questa è non una variabile globale.
Per avere una variabile 'globale' in Java si avrebbe qualcosa di simile a:
class Foo {
public static int bar;
}
I punti chiave sono che c'è solo un Foo.bar
nel codice ed è accessibile a tutto. La modifica a protected static int bar
ne ridurrà la visibilità, ma è ancora qualcosa che è uno stato condiviso globale.
D'altra parte una classe che assomiglia a:
class Foo {
protected int bar;
}
Questo ha un campo protetto accessibile solo ad alcune cose (come menzionato sopra) ed è una variabile di istanza - che esiste un'istanza per oggetto. Non è una variabile globale. Ci sono buone ragioni per avere un codice simile a questo (lo troverai spesso in classi astratte).
Especially if you've all the essential getter/setter declared, you should have zero protected variable and it should not affect anything else.
I getter e i setter sono diversi dall'accessibilità. Il modello di bean per Java spesso ne determina l'esistenza. In genere, in questo caso si hanno proprietà private anziché protette.
Sebbene indichi nuovamente che un campo protetto è uno di quelli in cui è visibile.
Nel contesto del test ...
Un approccio per rendere metodi specifici restituire un valore specifico è estendere la classe e riscrivere quel metodo. Questo è possibile solo se il metodo non è final
o private
.
Quindi, sì, potresti davvero usare questo approccio.
Tuttavia, qui c'è disagio nel fatto che devi assicurarti che la tua classe riscritta sia nei pacchetti di prova solo per assicurarti che non scivoli nel tuo codice di rilascio.
L'altra cosa è che quando lo fai, sei molto tentato di scrivere una logica addizionale che differisca sostanzialmente dalla classe estesa. Ciò introduce il pericolo che in realtà non testerai ciò che pensi di testare.
Entrambi questi problemi possono essere risolti prendendo in considerazione la classe nel codice di test e specificando in particolare i valori desiderati. Rende molto chiaro a cosa si sta andando dove senza logica aggiuntiva e che il codice non entra in produzione (le classi derise esistono solo in fase di esecuzione nei test).
Ci sono ancora trucchi da tenere d'occhio qui, perché ancora non ha rimosso la logica (lo ha appena estratto) e tu hai ancora bisogno di assicurarti quella parte funziona correttamente.
Ahh, ma "non puoi prendere in giro o testare facilmente i metodi privati", sottolineano le persone. "Se non puoi farlo facilmente, la gente non lo farà o lo farà male". E questo è vero.
Ma c'è un'altra opzione. La protezione del livello di default in Java. Vedi Controllo dell'accesso ai membri di una classe
package com.se.prog.demo;
class Foo {
public int bar() { return 42; }
protected int baz() { return 4; }
int qux() { return 7; }
private int xyzzy() { return 13; }
}
I metodi bar
, baz
e qux
possono essere facilmente derisi. qux
è accessibile solo da altre classi nello stesso pacchetto di com.se.prog.demo
- e tu controlla quell'elenco.
Con la struttura delle directory di maven , si avrebbe
src/main/java/com/se/prog/demo/Foo.java
^^^^^^
ma c'è anche
src/test/java/com/se/prog/demo/TestFoo.java
^^^^^^
che può accedere a qux()
in Foo consentendo il test unitario delle parti più goffe di Foo, senza esporlo al mondo (e alle sottoclassi di Foo).
In alcuni ambienti, questo è considerato un approccio migliore per i metodi che sono le viscere della classe, ma devono ancora essere testati o presi in giro rispetto a quelli protetti o privati.