2012-02-09 14 views
6

Posso chiamare le variabili in 2 modi.Modo corretto di ottenere variabili da un'altra classe

Uno è solo per farlo in questo modo:

MyClass myClass = new MyClass();  

myLocalVar = myClass.myVarVal; 

E l'altro modo è quello di utilizzare un getter come questo:

myLocalVar = myClass.getMyVarVal(); 

Entrambi i modi stanno lavorando bene, ma mi chiedevo cosa sarebbe il modo più efficiente/corretto per farlo?

Grazie

+3

Un sacco di risorse [qui] (http://stackoverflow.com/q/1568091/387852), [qui] (http://stackoverflow.com/q/565095/387852) e [qui] (http : //stackoverflow.com/q/996179/387852), ad esempio. –

+0

Ma cosa succede se ho come 50 variabili che descrivono un oggetto. Ad esempio, diciamo che ho un oggetto chiamato Car, e quindi ho un sacco di variabili come carType, carColor, carHP, carMaker, carName, carWheelBase, carMPG, carTransmission, carEngine, ecc ... ho bisogno di fare un getter e setter per ciascuno? Sembra un TON di ulteriore codifica .... – SkyeBoniwell

+2

I moderni IDE (come Eclipse) possono farlo automaticamente. Ma dovresti anche chiedertelo se hai bisogno di esporre quelle variabili al mondo esterno. Stai violando i buoni principi di incapsulamento? –

risposta

11

Entrambe le tecniche sono terribili, ma utilizzando il getter è la pratica comune (e più sicuro).

Per accedere a un membro di dati pubblici (a.k.a. campo pubblico o proprietà pubblica) di una classe, è necessario conoscere i dettagli di implementazione della classe (il nome del membro dati e il tipo di membro dati). Questa è una brutta cosa; rompe il concetto di OOP "nascondere le informazioni" e aumenta "l'accoppiamento".

L'uso di un getter è anche negativo (come in una cattiva pratica OOP) perché gli oggetti non sono solo involucri intorno ai dati; gli oggetti dovrebbero incapsulare funzionalità e dati. "memorizza questo valore qui in modo da poterlo recuperare più tardi" non è una funzionalità; è la funzionalità di hoot (come in una scimmia in un grido di gabbia). I getter sono; tuttavia, una pratica accettata in Java (e in altri linguaggi OOP-lite come C++ e C#).

Per non pensare che io sia una torre d'avorio più pura, ovviamente uso i getter; Io uso java, quindi uso i getter.

I getter sono perfetti per portare a termine il lavoro (nessun gioco di parole), semplicemente non andare in giro credendo che "IR gud OOP Prgmr", perché se usi getter non sei un "buon programmatore oop", sei solo un programmatore che si porta a termine il lavoro.

Modifica: Forse un modo migliore.

Il modo migliore è non utilizzare getter, ma progettare invece le classi in modo che espongano funzionalità e non dati. In pratica, c'è un punto in cui questo si rompe; ad esempio, se devi visualizzare un indirizzo su una pagina JSP, inserisci un bean nella richiesta (o sessione o blah) con l'indirizzo ed esporti i valori usando i getter. Un modo "più oop puro" sarebbe quello di mettere un bean che espone "visualizza l'indirizzo su una funzionalità jsp".

Edit2: Forse un esempio migliore.

Dire che lavoro per una compagnia telefonica, negli Stati Uniti, e ho un oggetto che rappresenta un numero di telefono del cliente. Questo potrebbe essere simile al seguente:

public class CustomerPhoneNumber 
{ 
    private String npa; // numbering plan area (google search nanp for more details) 
    private String nxx; // exchange. 
    private String serviceNumber; 

    public String toString() 
    { 
    return "(" + npa + ") " + nxx + "-" + serviceNumber; 
    } 

    public boolean equals(Object object) 
    { 
    ... standard equals implementation (assume this works) 
    } 
} 

Ora dicono ottengo un numero di telefono come input da una pagina web in forma String inputPhoneNumber. Ai fini della discussione, la classe che riceve questo input è chiamata "servlet".

Come posso rispondere a questa domanda: "Il numero di telefono inserito nella mia lista di oggetti CustomerPhoneNumber?"

L'opzione 1 consente di rendere pubblici i membri dati npa, nxx e serviceNumber e di accedervi. È terribile.

L'opzione 2 fornisce getter per npa, nxx e numero di servizio e li confronta con l'input. Anche terribile, troppi dettagli interni esposti.

L'opzione 3 fornisce un getter che restituisce il numero di telefono formattato (l'ho chiamato toString() sopra). Questo è più intelligente ma ancora terribile perché il servlet deve conoscere il formato che verrà utilizzato dal getter e assicurarsi che l'input sia formattato nello stesso modo.

L'opzione 4 (che io chiamo "Welcome to OOP") fornisce un metodo che accetta una stringa e restituisce true se corrisponde al numero del servizio clienti. Questo è meglio e potrebbe apparire come questo (il nome è lungo, ma sufficiente per questo esempio):

public boolean doesPhoneNumberMatchThisInput(final String input) 
{ 
    String formattedInput; 
    String formattedCustomerPhoneNumber = npa + nxx + serviceNumber; 

    formattedInput = ... strip all non-digits from input. 

    return StringUtils.equals(formattedCustomerPhoneNumber, formattedInput); 
} 

Questo è il vincitore, perché non i dettagli di implementazione sono esposti. Inoltre, toString può essere utilizzato per generare il numero di telefono su una pagina JSP.

StringUtils è parte di Apache Commons Lang.

+0

quindi c'è un modo migliore o i getter sono solo un male necessario? – SkyeBoniwell

+0

C'è un [articolo eccellente qui] (http://www.yegor256.com/2014/09/16/getters-and-setters-are-evil.html) per coloro che cercano una spiegazione più approfondita (vedi il * Una sezione Ball and A Dog * per un'analogia molto comprensibile.) –

8

Per motivi di encapsulation si dovrebbe sempre andare con la seconda alternativa.

myLocalVar = myClass.getMyVarVal(); 

L'efficienza saggia probabilmente non noterà alcuna differenza.

4

Utilizzare SEMPRE getter e setter per accedere alle proprietà!

Si dovrebbe anche dare un'occhiata a this.

1

myClass.getMyVarVal() è più lento poiché si tratta di una chiamata di metodo e quindi crea l'ingresso nello stack per il valore restituito, ecc. Ma è preferibile che la pratica OOP utilizzi i getter.

+2

Il linguaggio Java non impone che la chiamata al metodo debba essere implementata in questo modo. In effetti, molto probabilmente questo metodo verrà sottolineato. – aioobe

1
myLocalVar = myClass.getMyVarVal(); 

sarà bene usarlo se si sta lavorando con OOP concetto

2

Basta creare l'oggetto e object.variablename; o object.methodName(); può essere utilizzato per creare riferimenti non statici ... non è necessario alcun utilizzo di getter.

Problemi correlati