玩! 框架使用一个<lot>的静态
Waaah,玩! 框架有这么多的静态方法。 我在哪里上学,我们被告知永远不会使用任何静力学,但玩! 像没有明天一样使用它。 那好吗? 如果是这样,为什么?
我们(7人和我)正计划使用Play! 涉及Web应用程序的项目框架。 我们决定用Play来做! 因为看起来相当有趣,我们所有人都已经知道了Java,而且这个任务非常困难,所以我们想把重点放在实际的任务上,而不是学习如何用不同的语言编程。
我们总是被告知,但是, 永远不要在我们开发的任何Java程序中使用'static',但是当我看着Play! 呃…大约有一半的方法是静态的 </夸张>
我想,至less我们可以使用单例对象(通过使用Scala,例如^^)来编程我们的项目,但是我非常关心框架本身实际上有多less静态的。
那么,我应该关心这个吗? 玩的方式! 开发人员编程,使所有这些静态不会造成问题?
(例如, 这个线程有一个关于为什么静态成员应该不惜一切代价避免咆哮。
Play只有在有意义时才使用静态方法:
- 在控制器层,因为控制器不是面向对象的。 控制器充当HTTP世界(无状态,基于请求/响应)和完全面向对象的模型层之间的映射器。
- 在工厂方法的模型层中,像findAll(),count(),create()哪一个当然不依赖于任何特定的实例
- 在一些play.libs。*类提供纯粹的实用function
玩游戏的框架并不是一个很好的certificate,当使用静态是合适的,也没有certificate你的老师是错的。 游戏是一种欺骗,解决了Java语言之外的静态问题。
关键问题是你必须并行处理多个HTTP请求,而静态字段是“全局的”。 所以你需要每个线程一个实例(甚至更好,每个HTTP请求一个实例),但是其中的一些是通过Play中的静态方法返回的。 这是因为玩! 大量使用ThreadLocal
,所以它解决了Java语言之外的静态问题。 但那不是一切。 有人说控制器方法是合理的静态的。 当然,但在普通的Java中,这将是不方便的,因为那样你不能访问请求特定的数据没有某种types的前缀,如req.
在req.session
,然后你仍然必须从某个地方获得req
,比如作为静态控制器方法的参数,这更麻烦。 然而,在Play中,你可以直接写session
,就像静态字段。 这是因为Play使用字节码工具来将所有这些静态字段引用更改为更智能的。 再次,Java语言之外的解决scheme。 这些不是最后的静态字段。
所以,一般来说,避免非最终的静态。 尽pipe游戏对你有帮助,所以在这种情况下不要害怕他们。
从一个非常简短的看,我会说这是有道理的:Web请求是无状态的,所以没有对象接收请求(=方法)。 因此,将URI(如“/ articles / archive?date = 08/01/08&page = 2”)映射到名为archive()
的静态方法上,我想应用程序类是有意义的。
编辑现在在播放2.4, 注射是自动完成的。 所以只要在文件path中的控制器path的开头添加@就可以了:
GET / @controllers.Application.index()
对于旧版本(2.1到2.3),您将不得不在Global类中重写getControllerInstance,如Documentantion中所述。
与编程中的任何东西一样, 永远不会是正确的答案。 就像往常一样。 总有例外,正确的答案总是“取决于”。
确实,在纯粹的面向对象(我是所有的),静态的空间很小。 但是有时候他们只是有道理,这也是事实。
经典的例子是实用方法。 当然,如果我们可以将我们的abs()
方法追加到Integer,会更好。 但我们不能; 所以我们坚持Math.abs(int i)
。
我倾向于认为只有在与实例本身无关的情况下使方法成为静态才是正确的。 例如,在class级Person
,您可以有一个方法来获取人员列表,并返回今天有生日的人数。 也许你只能在类本身做这个,如果需要做计算的数据是私有的(OO纯粹主义者会理解的东西;)),但是这个方法显然与单个Person实例没有关系。
另一件事是内部课程。 如果你不需要与包含types的关系,你经常想使它们成为静态的。
我从来没有见过玩! 但是如果你说超过50%是静态的,那么我猜测它可能是devise不当的。 那也不例外。 很多框架是。 不要让它让你失望。 肯定不要从中学习!
但是,如果它的工作,你仍然可以使用它。
主要的问题是静态方法只能访问其他静态方法和字段,这导致了“静态粘附”,静态方法必须通过公共静态字段与应用程序的其余部分(其中包含协作者) ,这导致僵化。
免责声明:我不太了解'玩'!
静态控制器的方法肯定是Play的关注领域! 框架,并做了一些testing后,这是我没有做的主要原因玩! 在项目中。 实际上你可以在FOSS项目的哪里看到Play! 用来。 几乎没有控制器testing。 原因是,用静态方法,DI变得困难。 这是他们应该花更多时间在ASP.NET MVC上玩的地方! 已经有了一些启发。
通常你有这样的构造函数:
public HomeController( IService service ) { _service = service; } public Index() { var data = _service.getData(); return View( data ); }
然后使用DI将IService实现注入到Controller中。 重要的是在你的testing中,你可以在运行Controller之前实例化IService,然后根据你刚刚生成的IService来testing结果。
在播放这变得非常困难。 因此控制器unit testing变得困难。 对我来说,这是一个重大的问题。 因此,我倾向于寻找其他框架而不是Play! 在Java世界。 哎呀,为什么不去与原来的,只使用JRuby?
游戏中的静态方法主要用于控制器的动作方法。 这些方法只是为了从模型中提取必要的数据并将其暴露给视图。
它们以某种方式对应于每个可能的http请求,就像那些http请求是完全无状态的。
关于结构化编程,一方面你有程序,另一方面有variables,但是在OOP范例中,你将程序和variables视为一个整体。
也就是说,你有和实例方法(过程)和实例variables的对象。
但是控制器的动作是无状态的,也就是说,他们从请求中获取所有的variables(也可能来自caching,但在这种情况下,你需要一些最终来自请求的会话ID)。 所以控制器动作就像状态过程一样,这就是为什么它们不像模型那样特别适合OOP范例。
我想,至less我们可以使用单例对象
Java中的单例与使用所有静态方法没有多大区别。 作为国家也没有太多的存储空间。 我想你不应该担心。
那么,我应该关心这个吗? 玩的方式! 开发人员编程,使所有这些静态不会造成问题?
它不会。 事实上,没关系。
林也玩的静态方法的数量感到惊讶,但为什么不,如果它工作正常…
其实我不同意你的老师
如果一个对象没有状态(即全局variables),但只包含一些例子,那么使用对象而不是静态方法就没有任何好处。 除非您打算稍后添加一个状态(不应该共享的状态),或者如果您正在使用一个接口并希望能够轻松地切换实现,那么使用静态方法更容易。
JDK本身,apache commons或许多框架都包含静态方法:
- StringUtils的
- Pattern.matches(正则expression式,input)
———-
其实我想你想知道什么是像JPA.java类: https : //github.com/playframework/play/blob/master/framework/src/play/db/jpa/JPA.java
他们只使用静态方法并保持静态。 这可能是奇怪的,但实际上对我来说有点像使用单例,除了在静态上下文中使用方法而不是对象。 主要区别是你不必每次调用getInstance()。
我认为这是为了便于使用而devise的,因为调用“getInstance”并不方便用户使用,而且能够轻松地在任何地方(连接到线程)轻松获得会话,而不是使用xml或自动assembly注入sessionFactory。 ..
你的教授可能会告诉你,避免使用静态的,因为如果你不正确的使用它,会对你的devise造成危险。 但是注意在很多情况下,用单例replace静态方法并不能使你的devise更好。 即使您现在调用实例方法的方法,对象仍然会紧密耦合…
所以也许一个规则应该是避免使用静态,除非你不关心紧耦合。
-
在这种情况下,当您调用JPA.xxx()方法时,您的代码与框架的JPA类紧密耦合。 但我不认为游戏的devise是为了让您能够轻松地从一个框架切换到另一个框架,而不至less有一些返工。
-
这与EJB3规范或类似的东西有很大的区别:如果EJB3实体pipe理器的方法在静态的地方,你将被迫通过调用HibernateEntityManager.xxx()或ToplinkEntityManager.xxx()来将代码紧密地耦合到实现。 在这种情况下,有一个通用的接口(我们不能在接口上添加静态方法)。
———-
- 该类不是其他框架中使用的规范的一部分。
- JPA类只有一个实现:通过播放完成。 而他们可能不打算做第二个。
- 因此,当您使用Play框架时,对这个Play类的紧密耦合对我来说似乎是合适的。
Play采用了一种function性的方法,比如node.js ,比如在Java中,可以说Scala更有意义,例如Typesafe Stack正在推动。 正如其他海报所指出的那样,Java正在使用字节码工具(la Aspect J)进行扩展,以更无状态/function的方式运行; 斯卡拉默认这样做。
如果你是一个面向对象的编程纯粹主义者,你不应该使用static
方法/领域,但是他们可以安全地使用,并不一定是引起关注的恕我直言。
使用静态方法的原因之一是静态导入,它允许您缩短符号并使代码更具可读性。 在使用像Guava或Apache Commons这样的实用程序库时,这可能会有很多静态调用。
Play 2.1现在通过使用控制器注入来支持非静态控制器方法,所以目前还不清楚为什么他们从一开始就不在这里。
您现在可以在Play中使用Spring DI,请参阅https://stackoverflow.com/a/16552598/10433 。 我正在使用它,它迄今为止工作正常。