Play! framework uses a of statics

后端 未结 14 1871
太阳男子
太阳男子 2020-12-07 15:29

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

相关标签:
14条回答
  • 2020-12-07 16:01

    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:

    public HomeController( IService service ) {
       _service = service;
    }
    public Index() {
       var data = _service.getData();
       return View( data );
    }
    

    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?

    0 讨论(0)
  • 2020-12-07 16:01

    Play takes a functional approach, like node.js for example, and arguably makes 'more sense' in Scala than in Java, as the Typesafe Stack is pushing, for example. As other posters have pointed out, Java is being augmented using bytecode instrumentation (a la Aspect J) to behave in a more stateless/functional way; Scala does this by default.

    0 讨论(0)
  • 2020-12-07 16:13

    EDIT Now in Play 2.4, the injection is done automatically. So just adding @ at the beginning of the controller path in the file routes will make the trick:

    GET     /                  @controllers.Application.index()
    

    For older versions (2.1 to 2.3) you will have to override getControllerInstance in the Global class, like explained in the Documentantion.

    0 讨论(0)
  • 2020-12-07 16:15

    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:

    • StringUtils
    • Pattern.matches(regex,input)

    ----------

    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).

    ----------

    • That class is not part of a specification used on other frameworks.
    • The JPA class has just one implementation: the one done by play. And they probably are not planning to make a second one.
    • Thus a tight coupling to this Play class, while you are using Play framework, seems ok for me.
    0 讨论(0)
  • 2020-12-07 16:16

    I suppose, at the very least, we could use singleton objects

    Singleton in Java does not makes much difference than using all static. There is not much to store as state as well. I think you should not worry about it.

    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?

    It would not. In fact, it's alright.

    0 讨论(0)
  • 2020-12-07 16:17

    One of the reasons to use static methods are the static imports which allow you to shorten the notation and make the code more readable. This is specially true when using utility libraries like Guava or Apache Commons in which you might have a lot of static calls.

    Non-static controller methods are now supported in Play 2.1 via using controller injection, so it's not very clear why they were not there from start.

    0 讨论(0)
提交回复
热议问题