Waaah, the Play! framework has so many static methods. Where I go to school, we were told never ever to use any statics, yet Play! uses it like there's no tomorrow. Is that somehow okay? If so, why?
We (7 people and I) are planning to use the Play! framework for a project involving a web app. We decided to do it with Play! because it looks quite fun to do, all of us already know Java and the assignment is pretty hard so we wanted to focus on the actual assignment rather than also learning how to program in a different language.
We were always told, however, NEVER EVER to use 'static's in any Java program we developed, but when I look at Play! ... Well... about half the methods are static. </exaggeration>
I suppose, at the very least, we could use singleton objects (by using Scala, for example ^^) in order to program our project, but I'm quite concerned at how many statics there actually are in framework itself.
So, should I be concerned about this? Did the way the Play! developers programmed it make it so that all these statics don't pose a problem?
(For example, this thread has a rant about why static members should be avoided at all costs.)
As with anything in programming, never ever is never the right answer. Just like always. There are always exceptions and the right answer is always 'it depends'.
It's true that in pure OO (which I'm all for) there is very little room for statics. But it's also true that sometimes they just make sense.
The classic example is utility methods. Sure, it would be better if we could just append our
abs()
method to Integer. But we can't; so we're stuck withMath.abs(int i)
.I tend to think it's just correct to make a method static when it has nothing to do with the instance itself. For instance, in a class
Person
, you could have a method that takes a list of people, and returns the number of people that have a birthday today. Maybe you can only do this in the class itself if the data needed to do the calculation is private (something an OO purist would understand ;)) but still the method clearly has no relation to a single Person instance.Another thing is internal classes. You often want to make them static if you don't need the relation with the containing type.
I've never seen Play! but if you say that over 50% of it is static, then I'm guessing it was probably badly designed. That's no exception; a lot of frameworks are. Don't let it get you down. Definately don't learn from it!
But if it works you can still use it.
Play uses static methods only when it makes sense:
Static controller methods are certainly an area of concern with the Play! framework, and after having done some testing, it is the main reason for me not doing Play! in projects. You can actually see this where in FOSS projects where Play! is used. There is little or no Controller testing. The reason, with static methods, DI becomes difficult. This is where they should have spent even more time with ASP.NET MVC, from where Play! already takes a bit of inspiration.
Typically you have a constructor like this:
Then you use DI to inject the IService implementation into the Controller. The point being that in your tests, you can instantiate the IService just prior to running the Controller, and then test the result based on the IService you just produced.
In Play this becomes very hard. Thus Controller unit testing becomes hard. That is, to me, a significant problem. I would therefore tend to look for other frameworks than Play! in the Java world. Heck, why not go with the original and just use JRuby?
Im also surprised by the number of static methods in play, but why not if it works fine...
Actually i don't agree with your teacher.
If an object has no state (ie global variables) but just contains methods for exemple, it doesn't give you any benefits to use an object rather than static methods. Except if you are planning to add a state later (state that should not be shared), or if you are using an interface and want to be able to switch easily the implementation, it's easier to use static methods...
JDK itself, apache commons or many frameworks are including static methods:
----------
Actually i guess you wonder what's about classes like JPA.java: https://github.com/playframework/play/blob/master/framework/src/play/db/jpa/JPA.java
They use only static methods and keep a static state. This could be strange, but actually for me it's a bit like using a singleton except the methods are used on a static context instead of an object. The main difference is that you don't have to call getInstance() everytime.
I think this was designed like that for usability, because it is not user friendly to call "getInstance" and it's cool to be able to get easily a session everywhere (linked to the thread) instead of injecting the sessionFactory everywhere with xml or autowiring...
Your professor perhaps tells you to avoid using statics because it can be dangerous for your design if you don't use them right. But notice in many cases, replacing static methods by a singleton doesn't make your design better. Even if you now call the methods on an instance method, objects will still be tightly coupled...
So perhaps a rule should be to avoid using statics except when you don't really care about a tight coupling.
On this case, when you call JPA.xxx() methods, your code is tightly coupled to play framework's JPA class. But i don't think play is designed so that you would be able to easily switch from one framework to another without at least some rework...
It's a big difference with EJB3 spec or stuff like that: if the EJB3 entity manager's methods where static, you would be forced to tightly couple your code to the implementation by calling HibernateEntityManager.xxx() or ToplinkEntityManager.xxx(). In this case, there is a common interface (and we can't add static methods on interfaces).
----------
Play framework is not a good demonstration of when using statics is appropriate, nor it proves that your teacher was wrong. Play is kind of cheating, solves the issues of statics outside the Java language.
The key problem is that you have to process multiple HTTP requests in parallel, and static fields are "global". So you will need one instance per thread (or even better, one instance per HTTP request) for certain things, yet some of those things are returned by static methods in Play. That works because Play! uses
ThreadLocal
-s heavily, and so it solves a problem of statics outside the Java language. But that's not everything. Some say that controller methods are rightfully static. Sure, but in plain Java it would be inconvenient, as then you can't access request-specific data without some kind of prefix, likereq.
inreq.session
, and then you still have to getreq
from somewhere, like as a parameter of the static controller method, which is even more hassle. Yet in Play you can you just directly writesession
and like, they are just static fields. That's because Play uses bytecode instrumentation to change all those static field references to something smarter. Again, a solution outside the Java language. Those are not static fields at the end.So, in general, avoid non-final statics. Play does the magic for you though, so don't afraid of them in this case.
Statics method in play are mainly used in controllers action methods. These methods are meant to just fetch the necesary data from the model and expose it to views.
They correspond somehow to each possible http request, and, just like those http request are completely stateless.
On structural programming you have procedures on the one hand, and variables on the other, but on OOP paradigm you treat procedures and variables as a whole.
That is, you have and object with instance methods (procedures) and instance variables.
But controller actions are stateless, that is they get all there variables from the request (maybe also from the cache, but in that case you need some sort of session id that finally comes from the request). So controller actions are just like stateles procedures, and that's why they don't particularly fit in the OOP paradigm, as models do.