Crea metodi che non dipendono da campi di istanze, statici?

18

Recentemente ho iniziato a programmare in Groovy per un framework di test di integrazione, per un progetto Java. Uso Intellij IDEA con il plug-in Groovy e sono sorpreso di vedere un avviso per tutti i metodi non statici e non dipendono da alcun campo di istanza. In Java, tuttavia, questo non è un problema (almeno dal punto di vista dell'IDE).

Tutti i metodi che non dipendono da alcun campo di istanza dovrebbero essere trasformati in funzioni statiche? Se vero, è specifico per Groovy o è disponibile per OOP in generale? E perché?

    
posta m3th0dman 29.10.2013 - 09:02
fonte

4 risposte

22

Nota che IDEA ha questa ispezione anche per Java, si chiama Method potrebbe essere "statico" ,

This inspection reports any methods which may safely be made static. A method may be static if it doesn't reference any of its class' non static methods and non static fields and isn't overridden in a sub class...

Il fatto è che per il codice Java, questa ispezione è disattivata per impostazione predefinita (il programmatore può attivarla a propria discrezione). La ragione di ciò è molto probabilmente che la validità / utilità di tale ispezione potrebbe essere messa alla prova, sulla base di un paio di fonti abbastanza autorevoli.

Per iniziare, tutorial Java ufficiale è piuttosto restrittivo su quando i metodi dovrebbero essere statica:

A common use for static methods is to access static fields.

Dato sopra, si potrebbe obiettare che l'attivazione per impostazione predefinita dell'ispezione citata non è conforme all'uso consigliato del modificatore statico in Java.

Inoltre, ci sono altre due fonti che suggeriscono un approccio giudizioso sull'uso di idee che stanno alla base di questa ispezione o addirittura la scoraggiano.

Vedi ad esempio l'articolo di Java World - Mr. Happy Object insegna i metodi statici :

Any method that is independent of instance state is a candidate for being declared as static.

Note that I say "candidate for being declared as static." Even in the previous example nothing forces you to declare instances() as static. Declaring it as static just makes it more convenient to call since you do not need an instance to call the method. Sometimes you will have methods that don't seem to rely on instance state. You might not want to make these methods static. In fact you'll probably only want to declare them as static if you need to access them without an instance.

Moreover, even though you can declare such a method as static, you might not want to because of the inheritance issues that it interjects into your design. Take a look at "Effective Object-Oriented Design" to see some of the issues that you will face...

Un articolo sul blog di test di Google arriva addirittura a rivendicare Statico I metodi sono Death to Testability :

Lets do a mental exercise. Suppose your application has nothing but static methods. (Yes, code like that is possible to write, it is called procedural programming.) Now imagine the call graph of that application. If you try to execute a leaf method, you will have no issue setting up its state, and asserting all of the corner cases. The reason is that a leaf method makes no further calls. As you move further away from the leaves and closer to the root main() method it will be harder and harder to set up the state in your test and harder to assert things. Many things will become impossible to assert. Your tests will get progressively larger. Once you reach the main() method you no longer have a unit-test (as your unit is the whole application) you now have a scenario test. Imagine that the application you are trying to test is a word processor. There is not much you can assert from the main method...

Sometimes a static methods is a factory for other objects. This further exuberates the testing problem. In tests we rely on the fact that we can wire objects differently replacing important dependencies with mocks. Once a new operator is called we can not override the method with a sub-class. A caller of such a static factory is permanently bound to the concrete classes which the static factory method produced. In other words the damage of the static method is far beyond the static method itself. Butting object graph wiring and construction code into static method is extra bad, since object graph wiring is how we isolate things for testing...

Vedete, dato sopra sembra naturale che l'ispezione menzionata sia disattivata di default per Java.

Gli sviluppatori IDE avrebbero un molto tempo difficile spiegare perché pensano che sia così importante da impostare per impostazione predefinita, contro raccomandazioni e best practice ampiamente riconosciute.

Per Groovy, le cose sono abbastanza diverse. Nessuno degli argomenti sopra elencati si applica, in particolare quello sulla testabilità, come spiegato ad esempio in Metodi matematici di derisione in Groovy articolo su Javalobby:

If the Groovy class you're testing makes calls a static method on another Groovy class, then you could use the ExpandoMetaClass which allows you to dynamically add methods, constructors, properties and static methods...

Questa differenza è probabile perché le impostazioni predefinite per l'ispezione menzionata sono opposte in Groovy. Mentre in Java l'impostazione predefinita "on" sarebbe fonte di confusione per gli utenti, in Groovy, un'impostazione opposta potrebbe confondere gli utenti IDE.

"Ehi il metodo non usa campi di istanza, perché non mi hai avvertito?" A questa domanda sarebbe facile rispondere per Java (come spiegato sopra), ma per Groovy non ci sono spiegazioni convincenti.

    
risposta data 29.10.2013 - 20:48
fonte
5

È difficile immaginare che ciò possa avere effetti visibili sulle prestazioni. L'unico vantaggio che posso vedere per renderli static è che fornisce un'indicazione visiva che lo stato dell'istanza non è influenzato. In altre parole, dice alla persona che legge il codice sorgente qualcosa ... "interessante" su quel metodo, solo in virtù del fatto che è lì. La vera domanda è, chiarisce o confonde? "Perché questo metodo è statico? È un metodo di fabbrica? È la possibilità di chiamarlo senza un'istanza di oggetto necessaria?"

Inoltre, ad alcune persone non piacciono i metodi statici, perché affermano che non puoi prenderli in giro, e quindi non sono testabili, o qualcosa del genere. Certamente, se lo stai rendendo statico per uno qualsiasi dei soliti motivi, ad esempio fornire un metodo factory, ad esempio, sono tutto per quello. Non sono abbastanza sicuro che rendere i metodi statici solo perché non tocchino lo stato dell'istanza è un mandato.

    
risposta data 29.10.2013 - 18:35
fonte
2

Penso che sia possibile abilitare il possibile refactoring spotted .

Una volta che il metodo è stato reso statico, è chiaro che può essere spostato fuori dalla classe, ad esempio in una classe di unità.

È anche facile trasformarlo in un metodo di istanza di uno dei suoi parametri, spesso questo è il posto dove dovrebbe essere il codice.

    
risposta data 02.04.2014 - 00:17
fonte
-1

Si noti che è possibile avere classi stateless che implementano alcune interfacce (ad esempio java.lang.Runnable - non è possibile rendere statici i loro metodi. Alcuni pattern (ad esempio Strategy) possono anche produrre oggetti stateless che possono avere anche diversi metodi.

La statica è prima cugina dei singleton. Sarà davvero difficile passare da una statistica a una non statica in un secondo momento, quindi quando sarà necessario aggiungere lo stato sarai tentato di iniziare a introdurre variabili statiche.

    
risposta data 29.10.2013 - 21:52
fonte

Leggi altre domande sui tag