【51CTO快译】Ruby on rails是如此的优雅,简单,以及高效。我总是读到及听到诸如此类的评价。比如Bill Walton在他的《Rolling with Ruby on Rails Revisited》一文中就这样写到:
“现在我告诉你,通过Rails开发一个web应用能够比传统的Java框架快至少十倍,你会怎么想?”
哦,听听!快十倍!
事实上,听到了这些评论之后,我决定学习Ruby on Rails。我需要了解生产力以及编程乐趣的真正关键所在。
而摸了摸RoR之后,我发现它是一个非常传统的框架,使用着过时的技术:
◆Ruby是动态语言,这与Smalltalk一样。我偏爱静态语言。
◆Scaffolding使用被动的代码生成,这与IDE wizards或AppFuse一样。 我偏爱主动的代码生成,甚至更好的是没有代码生成。
◆以关系数据库为中心:代码生成器与ActiveRecord引导开发者先构思表格,其次才是类。我偏爱更加纯粹的OO,比如Hibernate,JPA,甚或是ODBMS。
◆MVC:我本来希望看到一个比老式MVC框架更有新意、更好的MVC。
Java的问题:Java开发者
Java世界中的生产力是个文化问题,而并非技术问题。那并非是Java的错,而是因为我们。我们Java开发者需要设计非常美观的架构,将GoF模式随处应用,实现一切(代码的)重复利用,将3 tiers放进我们所有的系统中,并为所有(产品)使用web服务。我们追求的不是简洁,所以我们才没有找到它。然而Java是个优雅的语言,使用它可以进行更加简单的软件开发。
Java的生产力:另一个渠道
提高生产力的方法之一是使用模型驱动的法子。那就是,开发模型的部分,事实上也仅仅开发我们应用中那模型的部分;然后用一个框架来以此为基础实现所有应用的开发。MDA,OpenXava,Trails,NakedObjects,RomaFramework以及JMatter都属于此类。
目的
我们要做的应用主界面外观如下:
基本上,该应用旨在实现以下三个功能:
◆显示食谱列表
◆创建新食谱,以及编辑现有食谱
◆将食谱归类(如“甜点”或“汤类”)
#p#
Ruby on Rails的***冲锋
RoR中,***步是创建一个新项目。在命令行下输入如下字段:
$ rails cookbook2 |
然后,创建并设置数据库。
之后则开始编写最初的代码。这里的话是SQL代码:
drop table if exists recipes; |
很明显,你需要在数据库中执行以上代码。
***就是,生成Ruby代码。你需要做的只是在你OS的shell下执行如下指令:
$ ruby script\generate scaffold recipe recipe $ ruby script\generate scaffold category category |
是的。你的RoR应用的最初版已经可以运行了。
是的,花费很少的功夫,一个简单的“create table”,外加执行一个wizard。接下来就是看看结果了。
Rails的结果
开发成果如下:
少干活,少结果。
#p#
JPA on OX的***冲锋
现在轮到OpenXava了。OpenXava下的***步是创建一个新项目:
$ ant CreateNewProject.xml -Dproject=CookBook |
然后,创建并设置数据库。
之后则是最初的代码编写,这里自然是Java:
Recipe.java:
package org.openxava.cookbook.model; |
Category.java:
package org.openxava.cookbook.model; |
***一步则是生成数据库图表,只要执行如下ant target即可:
$ ant updateSchema |
是的。你的OpenXava应用的最初版已经可以运行了。
是的,花费很少的功夫,一个简单的POJOs,外加执行“updateSchema”。接下来就是看看结果了。
OpenXava的结果
开发成果如下:
看,在这里用户可以创建,更新,删除,从列表生成PDF,将列表导出至excel,按单独列排序,对过长列表进行分页,以及数据的过滤。而且,无需任何代码,只需执行一个ant target,你便可以将应用部署在JSR-168的portal中,而且OpenXava的portlet在感官上与这个portal是一致的。
这里,***生成,便得到足以投入生产的应用。
少干活,得到细致的结果。
从哲学的角度来看,RoR与OX的差别就在于,在RoR中先写表格,OpenXava中先写类。
#p#
控制器
Rails已经生成了用于最基本的CRUD的控制器逻辑如下:
另一方面,OX并没有为CRUD生成任何代码。OpenXava只有一个泛型的用于CRUD和Printing的代码,这段代码自动指定到所有的实体上。你可以自己编写泛型CRUD逻辑,或者为某个实体编写特定的逻辑,但是一个用于每个实体的控制器代码是没有的。这种情况下,需要维护的代码量减少了,而你可以通过修改一处的代码来实现所有CRUD模块逻辑的改动。
也就是说,对于控制器,Rails使用生成代码,而OX使用泛型代码。
添加关系
要添加食谱与类别之间的关系,在Ruby下需要在category.rb中写入以下代码:
同时在recipe.rb中写下下段代码:
是的,相当简单。不过还有活儿要做。你需要编辑cookbook2\app\views\recipe\_form.rhtml,加入如下代码:
﹤p﹥﹤label |
结果如下:
在OpenXava中,则需要用JPA在Category.java中定义如下关系:
@ManyToOne(optional=false) @DescriptionsList |
下面是Recipe.java的:
@OneToMany(mappedBy="category") |
HTML就不用改了。应用看起来是这个效果:
从这里有链接通往修改及创建新类别的功能。
无需添加任何代码,用户在访问类别模块时便可以得到每个类别下的食谱列表,效果如下:
直至这里,RoR的应用还没有这个功能,为实现同样的功能,还需要一些额外的Ruby和HTML代码。
RoR和OX之间主要的区别在于,OX下无需编写HTML代码。事实上是,UI相关的代码你一句都不用写。
计算初始值
Ruby on Rails教程中的下一步,是生成一个属性的初始值。RoR中,这是通过编辑控制器代码来实现的。具体如下:
修改new以及update方法,添加下面这行代码:
@recipe.date = Time.now |
相对应的在OX中则是在模型中添加@DefaultValueCalculator注解:
@DefaultValueCalculator(CurrentDateCalculator.class) |
这样,通过更加有说明性的方法实现了相同的效果。
也就是说,RoR中将代码放入控制器中,OX下则把用于计算初始值,验证以及商业逻辑的代码放置在模型之中。OX提倡把商业逻辑从控制器中转移至模型。
另外,纯属好奇:RoR那篇文章中说“修改了模型文件,所以我需要重启web服务器。”使用Eclipse WTP时,我只需按下Ctrl-B,然后点击浏览器中的刷新,便可以看到我在OpenXava应用中修改模型的效果了。
结论
Ruby on Rails和OpenXava之间的主要区别在于RoR是一个MVC框架,你需要编写模型,视图及控制器。OX是一个模型驱动框架,你只需编写模型。结果就是,用更少的代码实现更好的应用。
另一个很大的不同就是RoR使用被动的代码生成;也就是说,它为你生成了代码,但是之后想要扩展或修改的话则需要手动编辑。OpenXava不使用代码生成,你有的代码都是自己写的。
在Java的宇宙间,你可以找到生产力。
原文:Java Kicks Ruby on Rails in the Butt by Javier Paniza
【编辑推荐】