java 玩!框架使用 <lot> 的静态
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5192904/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Play! framework uses a <lot> of statics
提问by Saew
Waaah, the Play! framework has so many static methods. Where I go to school, we were told never everto use any statics, yet Play! uses it like there's no tomorrow. Is that somehow okay? If so, why?
哇,好戏!框架有这么多静态方法。在我上学的地方,我们被告知永远不要使用任何静力学,但是 Play!像没有明天一样使用它。这样可以吗?如果是这样,为什么?
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.
我们(我和 7 个人)计划使用 Play!涉及 Web 应用程序的项目的框架。我们决定用 Play 来做这件事!因为它看起来很有趣,我们所有人都已经知道 Java,而且作业非常难,所以我们想专注于实际作业,而不是学习如何用不同的语言编程。
We were always told, however, NEVER EVERto use 'static's in any Java program we developed, but when I look at Play! ... Well... about half the methods are static. </exaggeration>
然而,我们总是被告知,永远不要在我们开发的任何 Java 程序中使用“静态”,但是当我查看 Play 时!...嗯...大约一半的方法是静态的。</夸张>
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.
我想,至少,我们可以使用单例对象(通过使用 Scala,例如 ^^)来对我们的项目进行编程,但我很担心框架本身实际上有多少静态。
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 threadhas a rant about why static members should be avoided at all costs.)
(例如,这个线程有一个关于为什么应该不惜一切代价避免使用静态成员的咆哮。)
回答by Guillaume Bort
Play uses static methods only when it makes sense:
Play 仅在有意义时才使用静态方法:
- in the controller layer, because controllers are not object oriented. Controllers act as mapper between the HTTP world (that is stateless, and request/response based) and the Model layer that is fully object oriented.
- in the model layer for factory methods, like findAll(), count(), create() which of course don't depend of any particular instances
- in some play.libs.* classes that provides purely utility functions
- 在控制器层,因为控制器不是面向对象的。控制器充当 HTTP 世界(即无状态,基于请求/响应)和完全面向对象的模型层之间的映射器。
- 在工厂方法的模型层中,例如 findAll()、count()、create(),它们当然不依赖于任何特定实例
- 在一些提供纯实用功能的 play.libs.* 类中
回答by ddekany
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.
Play 框架不能很好地证明何时使用静态是合适的,也不能证明你的老师是错的。Play 是一种作弊,解决了 Java 语言之外的静态问题。
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, like req.
in req.session
, and then you still have to get req
from somewhere, like as a parameter of the static controller method, which is even more hassle. Yet in Play you can you just directly write session
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.
关键问题是你必须并行处理多个 HTTP 请求,而静态字段是“全局的”。因此,对于某些事情,您将需要每个线程一个实例(或者更好,每个 HTTP 请求一个实例),但其中一些内容是由 Play 中的静态方法返回的。那是有效的,因为 Play! ThreadLocal
大量使用-s,因此它解决了 Java 语言之外的静态问题。但这还不是全部。有人说控制器方法是完全静态的。当然,但在普通 Java 中会很不方便,因为如果没有某种前缀,您将无法访问特定于请求的数据,例如req.
in req.session
,然后您仍然必须req
从某个地方获取,例如作为静态控制器方法的参数,那就更麻烦了。然而在 Play 你可以直接写session
就像,它们只是静态字段。那是因为 Play 使用字节码检测将所有这些静态字段引用更改为更智能的内容。同样,Java 语言之外的解决方案。最后这些不是静态字段。
So, in general, avoid non-final statics. Play does the magic for you though, so don't afraid of them in this case.
所以,一般来说,避免非最终静态。不过,Play 会为您带来魔力,所以在这种情况下不要害怕它们。
回答by unwind
From a very brief look, I'd say it kind of makes sense: web requests are stateless, so there isno object to receive the request (=the method). Thus, mapping an URI such as "/articles/archive?date=08/01/08&page=2" to a static method called archive()
on, I guess, your application class makes sense.
从一个非常简单的介绍一下,我会说这样的有道理:web请求是无状态的,所以是没有对象接收请求(=方法)。因此,将诸如“/articles/archive?date=08/01/08&page=2”之类的 URI 映射到调用的静态方法archive()
,我想,您的应用程序类是有意义的。
回答by Didac Montero
EDITNow in Play 2.4, the injectionis done automatically. So just adding @ at the beginning of the controller path in the file routes
will make the trick:
编辑现在在 Play 2.4 中,注入是自动完成的。因此,只需在文件中控制器路径的开头添加 @ 即可解决问题routes
:
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.
对于旧版本(2.1 到 2.3),您必须覆盖 Global 类中的 getControllerInstance ,如Documentantion中所述。
回答by Joeri Hendrickx
As with anything in programming, never everis 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.
确实,在纯 OO(我完全赞成)中,静力学的空间很小。但有时它们也确实有意义。
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 with Math.abs(int i)
.
经典的例子是实用方法。当然,如果我们可以将我们的abs()
方法附加到 Integer会更好。但我们不能;所以我们坚持使用Math.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.
我倾向于认为在与实例本身无关时将方法设为静态是正确的。例如,在 class 中Person
,您可以有一个方法来获取人员列表,并返回今天生日的人数。如果进行计算所需的数据是私有的(OO 纯粹主义者会理解;)),也许您只能在类本身中执行此操作,但该方法仍然显然与单个 Person 实例无关。
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.
没看过玩!但如果你说其中超过 50% 是静态的,那么我猜它可能设计得很糟糕。这也不例外;很多框架都是。不要让它让你失望。绝对不要学!
但如果它有效,你仍然可以使用它。
回答by Joeri Hendrickx
The main problem is that static methods only have access to other static methods and fields, which results in 'static cling' whereby the static methods have to rendezvous with the rest of the application (which contains its collaborators) via common static field(s), which leads to inflexibility.
主要问题是静态方法只能访问其他静态方法和字段,这导致“静态附着”,静态方法必须通过公共静态字段与应用程序的其余部分(包含其合作者)会合,这会导致不灵活。
Disclaimer: I don't know much about 'play!'
免责声明:我不太了解“玩!”
回答by Terje
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.
静态控制器方法当然是 Play 关注的领域!框架,做了一些测试后,这是我不做Play的主要原因!在项目中。您实际上可以在 FOSS 项目中的 Play 中看到这一点!用来。很少或没有控制器测试。原因是,使用静态方法,DI 变得困难。这是他们应该在 ASP.NET MVC 上花费更多时间的地方,从那里开始!已经需要一些灵感了。
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.
然后使用 DI 将 IService 实现注入到控制器中。关键是在您的测试中,您可以在运行控制器之前实例化 IService,然后根据您刚刚生成的 IService 测试结果。
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?
在 Play 这变得非常困难。因此控制器单元测试变得困难。这对我来说是一个重大问题。因此,我倾向于寻找除 Play 之外的其他框架!在 Java 世界中。哎呀,为什么不使用原始版本而只使用 JRuby?
回答by opensas
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.
它们以某种方式对应于每个可能的 http 请求,并且就像那些 http 请求是完全无状态的。
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.
在结构化编程中,您一方面拥有过程,另一方面拥有变量,但在 OOP 范式中,您将过程和变量视为一个整体。
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.
但是控制器操作是无状态的,也就是说,它们从请求中获取所有变量(也可能来自缓存,但在这种情况下,您需要某种最终来自请求的会话 ID)。所以控制器动作就像状态程序一样,这就是为什么它们不像模型那样特别适合 OOP 范式。
回答by Nishant
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.
Java 中的单例与使用所有静态没有太大区别。也没有多少要存储为状态。我认为你不应该担心。
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.
它不会。事实上,没关系。
回答by Sebastien Lorber
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:
JDK 本身、apache commons 或许多框架都包含静态方法:
- 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
其实我猜你想知道像 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.
他们只使用静态方法并保持静态。这可能很奇怪,但实际上对我来说这有点像使用单例,只是方法是在静态上下文而不是对象上使用的。主要区别在于您不必每次都调用 getInstance()。
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...
我认为这是为了可用性而设计的,因为调用“getInstance”不是用户友好的,并且能够轻松地在任何地方获得会话(链接到线程)而不是在任何地方使用 xml 或自动装配注入 sessionFactory 是很酷的。 ..
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).
在这种情况下,当您调用 JPA.xxx() 方法时,您的代码与播放框架的 JPA 类紧密耦合。但我不认为 play 的设计目的是让您能够轻松地从一个框架切换到另一个框架,而无需至少进行一些返工......
这与 EJB3 规范或类似内容有很大不同:如果 EJB3 实体管理器的方法是静态的,您将被迫通过调用 HibernateEntityManager.xxx() 或 ToplinkEntityManager.xxx() 将代码与实现紧密耦合。在这种情况下,有一个通用接口(并且我们不能在接口上添加静态方法)。
----------
----------
- 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.
- 该类不是用于其他框架的规范的一部分。
- JPA 类只有一种实现:一种通过游戏完成的实现。他们可能不打算制作第二个。
- 因此,当您使用 Play 框架时,与这个 Play 类的紧密耦合对我来说似乎没问题。