中国开发网: 论坛: 程序员情感CBD: 贴子 303103
haitao
Java 框架到底怎么了?
Java 框架到底怎么了?
如果你作为一个Java 程序员从事j2ee 开发的话,你一定会使用到众多应用程序框架。没有
任何一个语言会象java 语言社区那样活跃,任何一种新的程序理念都会很快在网上出现相
应的开源实现。对应最常用的网站开发模式MVC,每一层都会有很多框架,Struts, Tapestry
属于控制器层(C), Velocity 框架属于视图层(V), 你使用的数据持久层可能是Hibernate,
iBatis, OJB, 或者是JDO 的众多开源实现中的任何一个,比如JPOX 。但是你的选择太
多,未必是件好事,并不是任何人都能采用正确的框架来做正确的事情。如果你的开发平台
是.net, 那么你也许会避免这种情况,通常你只要安装一个Visual Studio .net 作为开发工
具,然后安装一个MSDN 来查找资料就可以了。对于程序开发人员来说,这是非常两难的
事情。我本人很喜欢Java ,无论是学习还是实践,它的确给我们提供了很多。但是为什么
我觉得.net 那样“一站式”解决方案在很多时候是正确的呢?
作为一个Java 程序员,我觉得Java 一些比较明显的问题,首先是Java 太复杂,其次Java 太
面向程序员了,而不是面向用户。相对C++ 来说, Java 已经很简单了。现在Java 程序
员数量如此多就说明了这点。但是正如有人曾经说过的那样,“在linux 上,你很容易区分
出谁是高手”,在Java 领域中就不那么容易了。我就经常发现身边的同事还在犯很低级的
概念性错误,他们甚至在无法准确地区分什么是接口,抽象类和Servlet 的情况下仍然可以
从事多年的j2ee 开发。但为什么又说Java 复杂呢,因为它完成一件事情,需要太多不同
的技术来实现了。这样对于那些概念不很清楚的程序员来说,你如何能保证他们作出正确的
选择呢?而众多框架中有没有多少提供“一站式”服务的。最近冒头的Spring 框架提供的
服务在众多的框架中算是最多的了,但是它又有个新问题,就是它还是太面向程序员了,而不是用户。为什么这么说呢?框架本来就是面向程序员的,这难道不对吗?Spring 虽然提
供了众多选择(但是还是不够多,它本身没有ORM ),但它没有提供简单的使用方式,所以
我们只能说它是面向程序员的。绝大多数java 框架都存在这个问题,就是学习曲线比较高。
我觉得学习曲线的高低是区分一个框架是否是面向程序员还是用户的关键,我想这主要表现
在框架的易用性上。其实框架最终的用户还是程序员,之所以用“用户”和“程序员”来区
分,是因为一些面向“程序员”的框架比较难以使用,虽然提供了大量的基础设施和零件,
但是还是要求程序员自己来组装。而面向“用户”的框架就简单一些,用户只要按照说明书
来使用就可以了。为什么Ruby on rails 会在Java 社区引发轰动,我想原因就在于此,它
提供了一个“一站式”面向用户的简单易用的框架,这是java 框架所缺乏的。为什么Ruby
on rails 能做到这点,难道java 本身做不到吗? 事实是众多Java 框架的设计者不这么做,
可能是他们的思维已经限制在如何用模式设计一个好的框架上了,而没有在框架的易用性上
做更多文章。使用过Spring 的人就知道它的xml 配置文件会渐渐的膨胀,虽然我们很容
易将其分解为更多的小配置文件来解决这个问题。但是在使用xml 配置文件上,它沿袭
了Java 编程的习惯性概念:“Java 是最好的编程语言,XML 是最好的描述数据的语言,
两者的结合是最完美的。如果一个应用不使用xml 来描述,那么它就不是好的java 应用”。

但是ruby on raiils 就是在这点上和众多java 框架区别开来,才达到了框架易用性上的一次
突破。这个思想贯穿了Rails 设计的始终:习惯约定优于配置。举个例子,通常我们写java
web 应用程序,都会按照MVC 来给对应类做区分,我个人喜欢将Controller 类放在web
目录中,将View 类放在view 目录中,将model 类放在domain 目录中。但是不同的人
有不同的设置,不同的命名,如何让框架知道这些不同的目录呢, java 框架的解决之道,
只能是通过xml 配置文件让它了解这些信息。而rails 的解决方式就是: 目录结构我来定
义,你只要在我定义好的目录中放东西就可以了。这也就是为什么rails 中很少有配置文
件(但不是没有)的一个重要原因。虽然思想很简单,但是它带来的好处就是,Rails 的开
发效率是java 开发的10 倍(这是rails 的fans 宣称的,不过我相信这点,相信看完这篇
文章你也一定会的)。那么光这点就能让rails 开发比采用java 更快了吗?不完全是这样,
因为这还得益于rails 的另外一个设计理念:更少的代码。并不是任何语言都能那么宣称
的,rails 实现这点完全得益于它的设计语言Ruby 。使用Ruby 你的确能用很少的语言写
很多的功能,这是其他语言所无法实现的。想要掌握Rails,你一定要了解Ruby。曾经有
人说:Zope (著名的python web 框架)是python 的killer 级应用,python 是zope 的秘密
武器。我想这句话用在描述rails 和ruby 的关系再合适不过了。那么我们还是来先了解
一下ruby 的一些基本概念吧。


Ruby 简介:
在开始写这个教程之前,我原打算简单介绍一下Rails 的使用就可以了,网上有相应的教
程,只要照着翻译一遍就行。但是有两个原因促使我要先介绍一下ruby: 一是:作为一个
Ruby 语言的爱好者,我觉得有必要向大家介绍它的好处。它是学习Rails 的关键所在。二
是:不先学习一些Ruby 的基本知识,Rails 一些代码你就会不明白原委。
Ruby 是由日本人松本行弘发明的一种面向对象的脚本语言。虽然很多语言都宣称自己是面
向对象的,但是每种语言的解释都不一样,大多是以它们自己特有的方式来解释什么是面向
对象,而实际情况中,这些面向对象语言又都采用了很多非面向对象的做法。以Java 为例:
如果你想对一个数字取绝对值,你会怎么做呢? java 的做法是
int c = Math.abs(-166);
也就是将一个数值传递给Math 类的一个静态函数abs 处理。为什么这么做?因为在java
中, 数值是基本类型不是类。

而在Ruby 中,任何事物都是类, 也就是说,数字–166 就是对象,取绝对值这样的操作
应该属于数字本身,所以”Ruby 方式”的做法就是:
c = -166.abs
这种做法是不是更直观一点。
接着我们来介绍一下ruby 语言的一些简单特点。

如何定义函数
def hello(name)
result = "hello, " + name
return result
end
这就是一个最简单的函数定义。Ruby 以def 开始一个函数定义,后跟着函数名, 然后是
参数,但是参数不必非要放在括号中, 你可以这样定义def hello name ,之所以要用括号
是为了更清晰。在ruby 中你可以用多种方式来完成同一件事情,这也是ruby 的设计思想。
Hello 函数很简单, 将参数和“hello, “字符串组合在一起,赋值给临时变量result ,然后
再返回result。你会注意到result 变量并没有申明,因为在ruby 中无需申明,变量在赋
值中自动使用。另外ruby 中不需要使用; 来结束每个语言,只要保持每条语句在单独一
行就可以。Ruby 也不包含{} 来定义块结构, if , when 函数都以一个end 关键字来结
束。缩进不是语法(python 程序员要失望了)。第一次使用ruby 我也有点不习惯,因为我
认为python 语言的缩进语法可以使得阅读程序代码更容易一些。但是学习了一段时间后,
我发现缩进语法并不是那么重要,Ruby 本身带来的帮助远比这个更重要。而且代码的易读
性也不是由缩进来改善的.此外上面的代码还可以更简化。
def hello (name)
" hello, #{name}"
end


在ruby 中,函数的最后一条语句如果是表达式,那么它就作为返回值。在上面的代码中,
用到了另外一个概念,就是表达式插入,字符串可以用单引号和双引号来括起来。但是两者
还是有一点区别。区别在于处理时间上的不同。如果使用单引号,那么处理的时间很短。如
果使用双引号,那么你可以插入变量,表达式,还有就是转意字符的替换,最常见的是\n,
\t 等。以上面的代码为例字符串中插入了变量name ,字符串中插入变量以# 开始,变
量放在{}中。但是特殊变量可以不用{}. 那么什么是特殊变量呢。这个也是ruby 特别的
地方。在Ruby 中,全局变量以$开头,静态变量,也就是类变量以@@ 开头,实例变量
以@ 开头。如果在字符串中引用实例变量,你可以这么写。
def hello
" hello, #@name"
end
关于变量和基本结构我们就简单介绍这些,下面我们要介绍一个重要的Ruby 概念。就是
interator (迭代器)。这个概念遍布在很多ruby 代码中,也是最常见的ruby way 。正是因
为interator ,在ruby 程序中,你很少会看到循环的使用。举个最简单的例子,如何打印
从1 到6 的结果。
在java 等语言中,我们的实现方法是:
for(int i = 1; i<6;i++) {
System.out.println(i);
}
而在ruby 中,一切皆为对象,数字本身就是对象(我们在前面已经介绍过了),数字本身有
它自己的迭代器times 。那么让我们看看它的实现。
6.times {|i| p i }
是不是很简单。
迭代器的概念很有趣,它是如何在ruby 中实现的呢。每个函数可以不光带有参数,还可以
在参数后面带一个代码块。代码块在ruby 中是以{} 和do end 来包围起来的。通常如果
是单行使用{} ,如果是多行这使用do end 。这并非强制,只是习惯性用法。
代码块和参数并不相同,它和函数的执行可以说是并行的,确切的说是接替进行。如果在函
数内部如何在运行过程中碰到了yield ,它就会将函数执行过程交给函数附带的代码块来执
行,代码快执行完了,执行流程转到函数内部继续运行。似乎很难理解,以下面这段代码来
理解可以会容易一些。
def callBlock
yield
yield
end


callBlock { puts "In the block" }
输出:
In the block
In the block
CallBlock 函数中只有两个yield 语句,它在执行过程中将执行权交给函数附带的block
运行,block 输出字符串"In the block" ,这样最终结果就是输出两行"In the block" 。在函
数内部使用yield 还可以带任意多参数。比如
yield a, b, c
这三个参数对应代码块中的三个参数{|x,y,z| p x y z }
好了, Ruby 就介绍到这里。下面正式进入正题,介绍一下Rails 的使用。

什么是rails ?
在写这个教程的最初,我基本上是在翻译网上的教程。但是rails 中包含了太多的程序和概念,如果只是简单的介绍,你虽然会很快学会使用rails ,但是对于它的一些概念了解不深。
在这里我希望更多地介绍一些rails 所包含的工具,比如rubygems , webrick 等等。
整个教程是基于ruby的windows 发行版。Ruby 作为跨平台的脚本语言,几乎在所有的平
台上都有相应的实现,很多linux 发行版本都带有了ruby安装文件,而windows 平台则需
要从www.rubyforge.net上下载一个one-click installer 安装程序。由于ruby one-click
installer 带有了rubygems package manager包,所以就省去了我们很多麻烦。我们只需要一
条命令就可以从网上下载rails 了(当然安装rails 你需要保证你的机器连上internet )。
简单介绍一下rubygems. Rubygems 是最近渐渐在ruby 社区流行起来的包管理工具。在
以前,如果你要下载一个ruby 扩展或者应用程序的话,你需要下载相应的zip 包,然后
解压缩,将应用或者扩展安装到ruby 对应的目录中。但是有了新的rubygems. 所有这些麻
烦都没有了,你只需要一条命令就可以从远程服务器上下载相应的包,如果相应的应用包含
其他扩展,rubygems 也会提示你从远程安装所依赖的扩展。安装后rubygems 会运行相应
的程序生成rdoc 帮助文档(类似于javadoc )。当然你也可以将软件包下载到本地运行
rubygems 的本地安装命令。有了rubygems 包管理器, ruby 应用的安装将变得前所未见
的容易。统一化的管理带来的好处就是简单。现在ruby 社区的应用都在朝着写gems 的
方向发展,很多以前的RAA 都转化为gems 了, 而rubygems 也将成为ruby 事实上的
包管理器标准了。记得以前看电影《指环王》的时候记得一句话,那就是“one ring to rule
them all”, 有了rubygems ,你可以说是“one gem to rule them all ” 了。
我的blog:http://szhaitao.blog.hexun.com & http://www.hoolee.com/user/haitao
--以上均为泛泛之谈--
不尽牛人滚滚来,无边硬伤纷纷现 人在江湖(出来的),哪能不挨刀(总归是要的)
网络对话,歧义纷生;你以为明白了对方的话,其实呢?

您所在的IP暂时不能使用低版本的QQ,请到:http://im.qq.com/下载安装最新版的QQ,感谢您对QQ的支持和使用

相关信息:


欢迎光临本社区,您还没有登录,不能发贴子。请在 这里登录