星期六, 九月 02, 2006

开放,还是限制? 这是问题

我最近有些懒散了,虽然开发工作还有很多,比如歌词,推荐文章的全文检索开发已经完成了一多半了,但是那么一点收尾的开发我却一直没做,还有 Flash 播放器的改造,整个代码还要做一次整理,一些已知的小Bug 也没改。我就是这样,稍微稳定就懒散,天生的懒惰。



现在“乐道”上真正推荐音乐的人只有我,impuise, yoyo, elseone, 如, 和 stella。 虽然 Rcissy 和 Dp 都有账号,但是他们一直没开始推荐。 有一些人留言问为什么没有“注册”的地方。其实这个网站不开放注册。这个决定是在我开发到一半的时候发生了变化。 原本我给“乐道”提出的口号是“人人都是DJ”,但是想想,这实在是个很荒唐的想法,是 Web2.0 流行综合征的结果。现在众多的 Web 2.0 网站都希望靠大量注册用户来提供内容,比赛谁的注册用户最多。其实这对于网站的品质并没有任何作用。新浪Blog打的是“明星博客”牌,他们认为明星就是社会精英,大家都愿意看看精英是怎么活的,哪怕他们写的是流水账,也会有人追捧。但是明星不一定就是精英,他们写的东西也不一定是精品。当然新浪有这个能力把众多明星招呼到自己麾下。而其他的网站就没那么幸运了,怎么办? 那么只能打草根牌了。 但是草根同样存在这个问题,草根里有精英,但是大部分仍旧是草根。这么多草根提供的内容有多少是真正值得一看的呢,这的确是个问题。随着 Web 2.0 的流行,还出现了另外一个问题,就是你已经无法控制众多注册用户提供的内容了,这些内容哪些是非法的,你没时间去了解,如果一旦出现了不正当的内容,那么你就需要花费大量的人力物力来监控,于是这些Web2.0 的网站出现了编辑和管理员,专门负责来删除这些帖子,这似乎又回到了Web 1.0 的时代了。 当然这还是那些有能力的大网站才能干的事情,对于小网站,我们能做些什么呢?



所以,开放注册,还是限制注册,这一直就是存在于 Web 2.0 的一个问题,只是这个概念来源于国外,对内容监管并不是那么严格。而在中国,一旦信息监管出现在身边,网站的所有者就要疲于奔命的检查所有这些来自草根的内容了。



“如果你无法控制每个帖子的内容的话,那么你能控制的就只能是那些发帖子的人了”。这就是我提出的"Web 1.1"的概念。当然这对于大多数崇尚自由精神的人来说,是无法接受的,尤其是那些艺术家们。我的朋友老蒋头一个向我发难,并给“乐道”起了个外号,叫“土人网”,呵呵。其实“乐道”这个网站的模式的确是比较特殊的,从现实生活中看,做电台DJ 工作的人始终是少数,而大多数人都是听众,实际上他们的话语权仅仅局限在给DJ 打电话。 是否人人都能成为 DJ ,这很难说,即便你有这个能力,你能否做到持之以恒地给大家推荐歌曲呢,还是三天打鱼,两天晒网;你是否能对一首歌曲作出自己的评论,而不是人云亦云,等等。这是一个实实在在的问题。当人们都在要求权力的时候,一旦被赋予了权力,他们是否能够尽自己应当的义务呢? 这的确是个问题啊。

程序思考:Ruby On Rails 网站开发感悟


独自一人花费了将近三个月的时间来做一个音乐网站(http://www.likenote.com ), 这对任何一个有过几年Web开发经验的人来说都不是件什么太难的事。虽然我也做了 4 年J2EE开发,但还是头一次使用全新技术来制作一个网站,这其中的辛苦却有点出乎我的意料之外。我大部分编程经验在 Windows 平台上,而这之前经过一番考察确定的技术方案,从操作系统,数据库,Web 服务器,到后台技术都是我不熟悉的。 我定下的开发时间是两个月,结果超出了一个月,实际花费在 ROR 开发上的时间只有3个多星期(RoR 的开发效率可见一斑),大部分时间在学习,学习上述的各种知识,它们对我来说都是陌生的,其中花费在学习服务器管理的时间就有一个多月,Rails 的学习花费了半个月(当然是读那本 Rails Book, 还有 Rails Recipes),还有 web 服务器和数据库也花费了一点时间。虽然网站的雏形已经出来,而且已经上线,但是我感觉真正的工作才开始。这将近三个月的学习和开发,自己总结了一些经验,对于那些打算独自开发 Web 项目的人可能有些借鉴作用。


1:首先也是最重要的一点:做一件事情的热情远比完成它所需要的技术更加重要。如果没有热情,就算是碰到一点小困难,你也会放弃,相反,就算是再大的困难你也能克服。


2:尽量不要到国内的任何技术论坛去提问,这既浪费自己的时间,也浪费别人的。因为通常简单的问题搜索网络就能找到,反倒会招来嘲笑;复杂的问题也不会有人给你解决,通常论坛上也可能解决不了。最好的方式是自己从 Google 上搜索。(这是经验谈)


3:CSDN 上的这篇文章非常好,虽然是转载自国外的。http://java.csdn.net/n/20060710/92484.html


其中我对第 6,11,15 条的感触最深。引用如下

15. "Build, learn, and make mistakes as you go--you'll know more about what you're doing as you're doing it, instead of before you do it." - Jason Fried, 37 Signals, advocating iterative development“一边做,一边建造、学习和犯错误——对你正在做的事情,你只有做了才会懂得更多,而不是事前空想。”——37Signals的Jason Fried鼓吹反复前进

注解:
国内程序员之间喜欢谈论技术的人多,真正闷头做事的人太少;各种论坛上相互争吵,辩论的多,写代码的人少。我也曾经是这样的人,很多东西都是停留在想法上,开始对 RoR 的顾虑也很多,性能啊,扩展啊。在网上搜索到很多这样的辩论,曾经动摇过我使用 ROR 的决心, 但是最终开发效率这一点最终占了上风。 其实仔细想想,你如果不喜欢一个东西,会找出有很多原因,如果喜欢它,一条理由就足够了。边学习边做的确是个好的方式,应该算是 Agile 的工作方式吧。那些考察讨论再三再开始做事的方式道象是 RUP 了。

11. "I like Google the best, they're the cleanest. Others are trying to take your attention away from what you're trying to focus on so it's counter productive to go to those sites." - Sasha, age 18, explains why it's smart to adapt to your customers instead of forcing them to adapt to you“我最喜欢Google,因为他们最干净。其他的网站则试图把你的注意力从你想要关注的东西移开。去那些网站不会有任何收获。”——18岁的Sasha指出,适应用户的习惯比起强迫用户去适应你的习惯要聪明得多


6. "Traditionally, people think more is better. More may work, but it's painful, expensive, very cold-war. Think about one-downing people, underdoing your competitors." - Fried coins some new verbs“传统上,人们认为多就是好。多也许能行,但它是费力的和昂贵的,充斥着冷战思维。想想看,可不可以向用户少提供些功能,比竞争对手更简单一点。”——Fried创造了一些新提法


这两条的理念是相同的,所以放在一起注解注解:这点的确很重要,我在开来始做网站的时候,界面设计选用了很复杂的页面模板,想到各种花哨的技术来堆砌它。后来觉得人家来你网站无非是推荐音乐,听音乐,评论,搜索,真正经常操作的就是这么一些简单功能,鼓捣花哨概念和技术的想法可能从最开始就是在远离你的用户。这的确是应该尽量避免的,如果不是读到这条,我可能也不会中途改版。


3:Ajax 看上去很美,但是它应该限制在某些特定功能的网站上(比如 Gmail, Google Map),整个网站采用它应该是不合适的。而且浏览器之间兼容的问题的确还是存在的。RoR 提供了非常简单的 Ajax 使用方式,有时候你会忍不住去采用它(Rails Recipes 这本书上充满了各种“奇技淫巧”),但是在做之前千万要考虑一下,这样做是否会给你的页面带来复杂性和服务器性能上的问题。在开发这个网站的开始,我也试验了很多 RoR 的Ajax 技术,但是后来都取消了,只保留了一个最简单的首页“最新留言”的动态显示功能。因为这个功能的确很有用。我将网站定位为一个多媒体的应用,所以采用 Flash RIA 来制作前端可能会更好, 整个网站采用 Flash 做前台比整个网站采用 Ajax 做前台更合理。原因如下:1:Flash 比 Ajax 更成熟2:Flash 有组件


4:如果你一个人制作整个网站,那么采用 RoR 是非常好的选择,原因当然是开发效率。整个网站从最开始有想法,到最终完成花费了三个月,其中学习时间占据了大部分,那么几个星期的开发时间就相当紧张了,如果采用 Java 可能根本无法想象。 其实搭建这么个音乐网站的想法,早在2001年就有了,我先后在论坛上推荐了四年的音乐,两年在博客上写音乐推荐。这期间我不是没有自己开发一个网站的想法,但是用 Java 实现起来太麻烦,我很多想法只是停留在脑海中,大部分时间用在考虑实现了,再加上我是个极为懒惰之人,看到那么麻烦的事情就不做了,直到 RoR 的出现,才使得这个网站得以完成。RoR 的好处在于:如果你有什么想法,你总是能很快的实现,只要你掌握了基本的技术,你就可以发挥你的想象来建设你的网站。 首页上泡泡框显示访客留言摘要的功能是我在一天早上5点醒来的时候想到的,爬起来用了两个小时就完成了它,很多人反映这个东西很好玩。


5:Web 2.0 的网站现在实在是太多,已经把整个市场搞坏了,前几天一个以前公司的朋友和几个人一起开了个公司,也是做 web 2.0 网站的,兴高采烈地把刚刚上线的网站地址给我,我一看,又是这种似曾相识的模板,似曾相识的应用。这种 Web2.0 站点的趋势就是:早期的ewb2.0国内站点抄袭国外的知名站点,后来的新进者抄袭国内已经成名的web2.0站点。如果这样的网站也有人投资那才叫怪了。 本来我也有开发网站寻找投资的想法,但是实在是想不出什么赢利模式,我也做不来这些写计划书的事情,还是自己凭兴趣做的好玩。朋友都说我的网站页面不适合商业站点,让我赶紧换了,我心里很清楚什么是他们说的商业页面模板,但是他们都说好,可我偏不喜欢。没法,还是按照我的想法来改造它吧。只要自己上班找个工作养活这个网站,或者更好的情况是,它能自己维持自己,这我就心满意足了。


6:现在的 RoR 实在是太火了,大有大家同上一条船的架式,搞 RoR 的人以它为荣,以搞 Java 为耻,估计也能写出个八荣八耻。但是它只是一种技术,众多后台技术中的一种,网站的访问者并不会因为你使用了 RoR 就给你掏钱,甚至是留下个好印象。网站的内容是主要的,掌握了它并不意为着能制作一个好网站。常言说:拥有榔头并不意为着你就是个建筑师 ,也不能让满地都是钉子。要么你去给人敲钉子为生,或者指导别人如何敲钉子,再或者找到一个好木场自己建个房子。“去 RoR 化”可能是我要做的下一个工作,把前台用 Flash 重建,采用 RoR 的 builder view 技术来传递信息。我个人感觉这个音乐网站有个好的想法,不管它是否能挣钱。首先是音乐推荐的确能给人带来快乐,做这样的网站才有趣。技术应该是实现你想法的工具,如果网站成为技术的试验品,对我来说就没有什么意思了。

程序思考: 关于“框架”


我做Java编程大概有四年了,但我仍然处在从Java初级程序员向中级程序员过渡的阶段。 Java 包含的东西实在太多,三大体系 J2ME,J2SE,J2EE 每个都包含了大量的内容,身为一个 Java 程序员其实挺悲哀的,不仅要不停地学习那么多基础知识,还要应付层出不穷的框架。不光要学理论,还要注重实践。想想原来搞 Perl, PHP 的时候,哪来的那么多知识点。虽然我的Java水平不高,但我始终对要学的东西保持自己的看法,对于技术我总是抱着怀疑一切的态度,有时候甚至很固执,就算我是错的,我也要自己撞了南墙来体验。我的观点是:"好话左右不了我,我会自己判断的。大家都说好,我可能偏不喜欢"。


我曾经在编程技术上做过四次选择:1:选择了 Velocity ,放弃了 JSP.2: 选择了 Ruby ,放弃了 Python.3: 选择了 Hivemind, 放弃了 Spring.4: 选择了 Intellij, 放弃了 Eclipse.
四年前第一次接触 Java WEB 编程的时候,我没有选择学习 JSP ,而是选择了 Apache 的 Velocity 框架。当时的 freemarker 也是相同类型的模板引擎,它甚至可以在模板中使用 JSP 的Taglib,我仍然选择了 Velocity ,因为我觉得视图层并不需要那么复杂。 Velocity 框架很简单,模板语言只负责简单的显示逻辑处理,速度更快,没有 JSP 第一次编译的速度延迟,而且它是一个通用的模板引擎,不光用于 Web 开发,如今它还被用在了 Intellij 中做为代码生成的工具。Freemarker 在模板中使用 Jsp Tag 的功能在我看来是个累赘,使得本来简单的东西添加了复杂性,所以我没有选择它。JSP 从一开始设计就是错误的,它没有及时避免出现失控的情形(页面中充斥 Java 代码,这就类似于 C++ 没有从一开始避免程序员写 C 那样的过程代码一样。而且 Taglib 也不是一个好的扩展显示逻辑的方式。


我在接触 Java 前曾经使用过一段 Zope 和 Python ,即便是在使用了 Java 两年后,我仍在研究 Zope 和 Python 。 使用 Python 这样的脚本语言主要是为了编写一些Java代码生成工具。如果用 Java 来写这种工具,无论编写还是发布都显得不那么完善。脚本语言最擅长是处理文本字符,文件,它们通常内置正则表达式功能,这些都成了编写Code generator 的强有力的工具。 Zope 建立 Web 站点的能力是有目共睹的,相对 Java 来说,它的开发效率更好,虽然执行效率较低,但是满足大多数中小规模网站的制作。接触了 Ruby 后,我逐渐离开了 Python。 原因是 Ruby 在编程中给我了一种从未有过的快乐感。我曾经认为 Python 的缩进语法是它的优势,因为这种强制性使得代码的可读性大大的增强了,即便是多年之后再看自己写的代码,或者是别人写的代码,你还是很容易读懂。但是 Python 语言本身的一些弱点,使得你感觉很不舒服,它的面向对象不彻底,只是具备一些 OO 的特点,使得在使用它的时候有点四不象的感觉。如果你用过 Ruby 这种感觉会更加强烈。不过这种选择取决于你是否是一个“面向对象编程”的强烈爱好者,否则 Python 长期积累的现成的成熟代码库会使得你很容易的选择它的。我想对我个人编程影响最大的一本书,当属 Dave Thomas 的那本 "Programming Ruby"的电子版了。通过它我才得以系统地学习了 Ruby ,并把我以前用 Python 写的脚本程序全部替换为 Ruby 脚本。直到现在,文件操作和数据库备份移植的脚本文件我都采用 Ruby ,而这些操作如果用 Java 来写,复杂性可想而知 。所以我一直认为一个程序员至少应该掌握一种脚本语言,并非为了学习脚本语言而学习它,主要是为了让自己的编程工作更轻松一点。至于后来放弃 Zope 而选择 ROR ,就是再自然不过的事情了。


Spring 的流行其实应该算是 Java 世界反对 Sun EJB 技术的一个必然结果,就算不是 Rod Johnson 推出 Spring 框架,大家也必然会采用另外一个人推出一个基于 POJO 的 IOC 容器框架的。其实在那个时候推出了很多 IOC 容器框架,比如 Pico Container, 还有那生不逢时的 Avalon,这些框架都或多或少有些问题。Pico 只是个简单的 IOC 容器,功能相对较弱。Avalon 不仅仅是个 IOC 容器,它更是一个组件框架。但是它是 type-1 型的框架,也就是说它是基于接口的服务,它的缺点是你必须实现一个特定的接口,这就造成了对特定框架的依赖性。早期的容器采用这种方式有其历史原因,后来推出的 IOC 容器不是采用 type-2(Setter)设置属性的方式来设置依赖关系,就是采用 type-3 (constructor) 构造函数的方式来设置依赖关系。Spring 和 Pico 就是如此,虽然两者都同时支持 type-2 和 Type-3 ,但是 Spring 更多使用 Setter 设置依赖关系,而 Pico 习惯采用构造函数。现在很多人都夸大 type-1 型这种接口依赖性的缺点,认为这是过时的框架(事实上 Avalon 框架最终被 Apache 组织放弃了)。 其实我并不这么看,我们公司使用 Avalon , Cocoon 框架很多年,对于一个多年使用 Avalon 框架的用户, 对过去代码的依赖性可能使得它不会简单地抛弃它,Avalon 组件式开发方式有其优势,在部署的时候有极大的好处,这点我在后面谈到 Hivemind 的时候详细再说。必须继承某个框架的特定接口,会使得将本框架代码移植到新框架的时候出现依赖性问题,但是如果你不存在更换框架的可能性的话,使用这种 Type-1 型框架就没有什么太大的缺点了。人们总是喜欢设置假想的未来预期,比如尽量少用数据库存储过程,因为这样产生数据库移植的困难,事实上真正企业级的项目很少会更换数据库层的,这点Rod Johnson 在他那本名著《Expert One-on-One J2EE Design And Development 》的第一章就做了阐述。所以对 Type-1 型框架的恐惧也是没道理的。 如果你已经在使用这样的框架,那么就坚持继续使用它,它的成熟性可能会给你带来更大的开发益处,但是如果你是个新手,那么最好还是采用 2 和 3 型的框架,能避免依赖性的时候还是应该尽量去做。


Spring 现在可以被看作是一个 FullStack 的全功能性框架,它不象 Struts 那样仅仅是个简单的 MVC 视图层框架,它包含了对 J2ee 开发各个方面的支持。在接触 Spring 框架之前,我就通过阅读 Rod Johnson 的 Expert One-on-One J2EE Design And Development 获益非浅,书中的各种真知灼见对任何一个开发者都有很大的启发,即便他不采用 Spring 来开发自己的应用。现在看来 ,Spring 在 Java 语言层次上已经做到了尽可能的简化和正确的决策。随着对它的了解日益加深,我发现它存在一些问题。大家都说 Spring 的XML配置文件太多了,其实我并不这么认为。看看 Hivemind ,Avalon 这些流行框架,哪个 XML都不少,这是 Java 框架的通病。 Spring 有一个优秀的 IOC 容器,它容纳的是 POJO ,但是它并没有发展成为一个组件框架。Rod Johnson 说"面向对象比某些技术本身更重要",Spring 也是这么做的,使用它你可以容易的面向接口编程,但是面向对象编程跟面向组件编程是两个阶段,面向对象主要是在开发阶段,而面向组件编程,更关注于部署 Deploy 阶段的工作。 一个面向组件的框架要考虑更多的动态部署的问题。 Spring 的问题出在部署上,如果你用过 Avalon 和 Hivemind, 你会觉得它们那种通过替换 Jar 包来更新功能的方式真的很爽,而这种特点在 Spring 中却看不到。 在 Spring 编程中,你会看到清晰的分层:表现层代码,应用层代码,数据持久层代码,它们各司其职,靠的是XML 配置文件来描述各层代码之间的依赖关系。所有这些代码和 XML 配置文件是放在一起的,Spring 应用的部署就是一种 "All or Nothing "的局面,更新一小段代码, 你就要更新整个应用的部署.如果采用 Avalon 或 Hivemind 这样的组件框架, 优势就明显了. 使用这样的组件框架来开发应用, 通常将程序员分类两类: 组件或服务开发者(系统程序员), 应用程序员. 系统程序员负责开发组件或者(服务), 供应用程序员调用. 举个例子, 如果要开发一个网页计数器的应用, 我可以将计数器的功能先定义接口 Counter,然后提供默认实现, 如果你采用文件来记录计数器的数值,可以提供一个 CouterFileImpl 的实现类, 如果采用数据库来记录数值,那么可以提供一个 CounterDBImpl 的实现类. 这种服务的概念,将原来的应用开发三层的概念(表现层,应用层,数据持久层)简化为两层(应用层,服务层), 原来的表现层对应应用层,由应用程序员开发, 而原来的应用层和数据持久层对应服务层,由系统程序员开发. 现在流行的各种表现层框架虽然是按照 MVC 模式设计的, 但是大多只是实现了 VC (视图和控制器),而对于M(模型)并没有提供什么支持. 以前这些框架多是推荐采用 Session Bean 来实现模型(M), 但是随着Spring 等POJO IOC 框架的流行, 模型的实现可以采用 Spring POJO , 和Avalon, Hivemind 服务来替代实现. 应用程序员可以采用任何流行的表现层框架来获取这些服务完成显示的任务. Spring 的问题出现在这里: Spring不是组件框架,沿袭原有的三层的概念, 是以 XML 来组织所有三层代码. 如果要改任何一层的代码,就牵扯到整个代码同时更新和部署. 其实这个问题还是可以通过 Maven 将不同包编译为 Jar 来解决, 但这不如组件框架直接提供这样的服务好. 如果采用 Hivemind ,可以将服务接口和对应服务实现编译为 Jar 包, 接口可以定义在一个Jar 包中, 不同的实现也可以定义在不同的 Jar 包中, 当然接口和所有的实现也可以都放在一个 Jar 包中. 这样如果后台实现变化了(文本记录改为数据库记录),那么系统程序员只要提供一个新的Jar(可以只更新Jar中的配置,修改默认实现的指向)给应用程序员, 这个修改部署就是以Jar包为最小单位.它的简单性是 Spring 提供不了的. 如果你看过 Howard Lewis Ship (Tapestry 和 Hivemind 框架的创始人)的日记, 就会知道他曾经在多年前阐述过这个问题, 并就此跟 Spring 框架的创始人 Rod Johnson 在多个研讨会上交流过,无奈 Rod 有自己的观点, 没有接受 Howard 的意见, 所以才有了后来 Hivemind 框架的问世. Spring 鼓励程序员采用面向对象思想,面向接口编程, 但是没有针对面向组件提供帮助. 面向组件编程更多的是考虑部署的概念, 如何从当前应用的类路径中动态找寻一个类,类路径下存在一个类的多个版本,应该如何确定加在的版本等等. 拥有组件框架对于应用程序开发者来说有极大的好处, 无论采用什么表现层框架,它都可以轻易的调用服务, 对它来说, 后台应用逻辑的更新, 持久层的更换也只是一个Jar包替换的问题. 如果表现层框架换了, 调用现有服务也是很容易的. Spring 基本上是采用XML来描述各个POJO 之间的依赖关系, 通过 Setter 或 Constructor 注入. 我觉得"在表现层依然采用 IOC 注入方式" 也是一个问题, 如果采用 Hivemind , 使用 Struts 做表现层,你可以通过 Service Locator 的方式获得服务, 而采用 Tapestry 你也可以采用 IOC 方式注入 Hivemind 服务. 这样对应用程序开发人员来说就非常灵活了. 所以我推荐大家采用 Hivemind 这种新型的 IOC 组件框架来开发 Java web 应用.


我发现大多数使用 Java 一两年的程序员都喜欢构造自己的"完美"组合开发框架, 我也是如此. 不过这方面做的最"过分"的当属 Matt Raible , 这位仁兄创建了 Appfuse 这个Starter 框架, 它结合了当今所有流行的框架加以组合来开发一个简单应用. 当初只是一个实验性的模型, 新的版本已经非常复杂了. Appfuse 也是采用三层组合,每层中都采用最流行的框架, 不过相对来说, 应用层和数据持久层采用的框架比较稳定,就是 Spring 和 Hibernate , 最近数据持久层又添加了 iBatis 和 JDO, 不过最丰富的当属表现层了, 当今主流的 Web 框架,他用了一遍, Webworks, spring mvc, struts, tapestry, jsf . 其实 Matt 现在做的有点过头了, 我承认我自己也是通过学习他的 Spring Live 一书来了解 Spring 开发的. 我对他那个相对简单的 equinox (Appfuse Light 版本)框架更感兴趣一点, 现在的 Appfuse 对我来说,已经膨胀到无法看下去的地步了. 其实他如此组合没有什么太大的意义,最终程序员都会有自己的"完美"方案的. 我的选择是 Spring MVC + Hivemind + Hibernate . 以前中间应用层我是采用 Spring , 因为 Spring 和 Hibernate 的结合比较完美, Template 的确简化了代码量,使用也很简单. 但是随着 Hibernate 3.x 的推出, 原有的 Checked Exception 都改为 Unchecked Exception 了, 使用 Spring 的优势就不那么明显了, 而组件框架部署的优势就成了首先考虑的问题. Spring MVC 是 Spring 框架中一个从头开发的子框架, 它的设计比较完善,功能很多: 多视图层输出, 向导页面等等, 如果你采用Flash 来制作 RIA 应用就可以采用 Velocity做视图层生成 XML 数据, 也可以利用 Spring 的 Webservice 集成功能. 这是我心目中一个完美的组合.


现在还有不少人正在继续构造自己“完美”的框架,其实这种追求完美的过程是永无止境的,正如那个广告中说的“没有最好,只有更好”。记得以前看《六人行》第一季中有这么一集,Chandler 公司的一个女同事说要给他介绍一个“完美”的男友,Chandler 说了这么一句话 “Ah, y'see, perfect might be a problem. Had you said 'co-dependent', or 'self-destructive'”,当时我并没有理解这句话的意思,现在觉得这似乎是描述这种追求完美框架行为最合适的一句话了。我想,可能有不少Java程序员跟我一样,打算寻找一个最完美的组合框架来做一个自己的应用,结果这个应用过了一两年都没完成。Java 程序员过于重视理论上完美的设计,而忽略实际的效果。看看如此众多的 Java 框架竟然构造不出一个好的论坛程序,所有出色的论坛都是出自 PHP 和 PERL,的确很 让 Java 程序员羞愧的。现在看来,真正的 Pragmatic Programmer( 实用主义程序员)都来自这些脚本语言的使用者,他们没那么多思想包袱,是真正笃信“实践出真知”的一群人, Java 社区应该多向他们学习。对于 Java 程序员来说,关键不在于你是否寻找到一个完美的框架组合,而是要做出一个好的应用。在论坛与人空谈,与人论战是没有任何意义的, David Heinemeier Hansson 建立 Rails 是在做项目的过程中产生的,他没有采用任何已有的框架,也没有去和别人辩论,而是靠实事说话把整个 Java 业界搅的天翻地覆。 我想这点值得广大 Java 程序员深思。

程序思考:“主动程序员”vs“被动程序员”


我觉得这个世界上的程序员可以分为两种:"主动程序员"和"被动程序员"。"主动程序员"可以自己选择开发方式,开发语言和框架,"被动程序员"被动接受公司指定的语言和开发方式。其实在现实生活中,这种分类并不绝对,一个程序员可能在不同的时候担当不同的角色,"被动程序员"也可能享有有限的主动权。这么分类并不以程序员本身的知名度,财富多少,是否自己创业还是受雇于人有关。David Heinemeier Hansson 受雇与 37 Signal ,但是仍然可以自己选择建立自己的 Rails 框架来完成项目,他应该算是个"主动程序员"。Firebird 数据库的领导者同时也是 Interbase 数据库的创始人 Jim Starkey 将自己的公司卖给了 Mysql AB 而不得不给 Mysql 干活,从某方面说,他应该是个"被动程序员"。大多数第三世界国家的程序员应该属于"被动程序员",他们编程只是为了一份养家糊口的工作,他们无权选择自己喜欢的编程语言或者框架,因为这是公司给他选择的,因为如果选了其他,他可能就找不到工作了。曾经有个即将离职的同事让我给他推荐一个比较好的编程框架,可以很容易完成一个网站的制作,我给他推荐了 Zope, 还有 Rails, 他听我的介绍觉得不错 ,当我告诉他必须学习 python 和 Ruby 编程语言时,他显得很惊愕,"那能找到工作吗?"。这话其实也表达了大多数国内程序员的想法。看看招聘网站就知道,现在最需要的程序员是 Java 程序员,最需要了解的框架是 Struts。如果不会你很难得到面试的机会,所以就算你不会也要在自己的简历中"修饰"一下。



有些自己创业的人可以自己选择喜欢的编程语言和框架,当然那毕竟是少数。如果我能够选择的话,我肯定不用 Java 来做网站应用。因为它完成一个简单的工作太麻烦了,很难快速适应需求的变化。当然我也不会去用 PHP ,因为我已经习惯了面向对象的编程方式了。 我发现一个奇怪的现象:大多数转向学习 Ruby on rails 框架的人都是来自 Java 阵营的程序员,而转向Python 框架Zope,django 的程序员大多有 ASP,PHP 背景。因为 Ruby 是一个真正的面向对象的语言, 它同时具备了脚本语言的特点,而 Python 首先是一个脚本语言,它具备了一些 OO 的特征。Java 程序员 很难忍受走回头路,所以他们选择了一个比Java更面向对象的语言 Ruby ,而PHP,ASP程序员没有那么重的思想负担,他们选择 Python 可能是因为它的代码更 Beauty ,远比他们以前写的"意大利面条"式的PHP,ASP 代码要干净的多。 无论是 python, 还是 Ruby 这些非主流程序语言开发的框架,使用起来都异常的简便,他们可谓是真正从程序员角度考虑的框架。为什么 Ruby 一出,搅的 Java 的世界一片混乱,我想原因还是出在 Java 这里,当 Java 程序员想当然地认为程序开发应该如此麻烦的时候,Rails 的出现让他们立刻觉得被这些所谓的 Java 流行框架和 Sun 给欺骗了,这种欺骗是如此之深,以至于他们中间有的人"头也不回"的离开了 Java, 转而攻击 Java 的种种不是。这其中比较有名的人就是 Bruce Tate ,这位老兄写了两本轰动 Java 世界的书,Spring: A Developer's Notebook 和 Better, Faster, Lighter Java (该书可是获得 Jolt 大奖的,恰好我还都读过),随着 Rails 的流行,这位仁兄立刻叛逃出 Java 阵营,写了 Beyond Java 一书,着重介绍了一些非Java 框架,比如 Smalltalk 的Seaside, 和 Rails。


Java 为什么这么复杂,我想了很久,得出这么个结论:这是因为 Sun 希望它那么复杂。为什么这么说呢?Sun 不是一个好的软件公司,它最擅长做的是制定规范,这很类似Java 编程中的 Interface, 经常编写 Java 程序的人,会发现 Interface 可能是出现最多的一个词汇了,任何框架中都充满了Interface —接口,大多数编程书都推荐面向接口编程(当然这不是Java的错,是设计模式要求的,不过 Java 将此发挥的最好)。首先定义接口,然后针对接口编写不同的实现,至少提供默认的实现。Sun 也是如此,看看 J2ee 的规范包含了多少 J 打头的技术, JDBC,JNI,JCA,JDO,JPA .... ,现在的 JCP 组织更加如此,每隔一段时间,就有大量的规范问世,Draft 的,还是 Final 的,充斥着Java 世界,这是 Sun 希望的, 每定义一个规范,就会有很多厂商来实现它,Java 的软件市场就做大了,这样 Sun 就可以靠授权,认证拿更多的钱,你看 Sun 的股票那么低迷,而却拥有那么雄厚的流动资金,原因再明白不过了,只要 Sun 还拥有 Java ,它就拥有了一切。Sun 希望 Java 变得复杂,就如同程序员希望 Perl 代码难看一样,这样做是可以带来好处的。Java 的复杂性也带来了产业链上其他行业的繁荣,比如咨询,在 Php ,Perl 流行 Internet 的年代,网站开发似乎还不需要咨询师,包括 C/S 盛行的时候,企业开发也不需要咨询师,然而随着 J2EE 逐步主宰企业级开发,咨询行业也开始兴旺起来。企业大把大把的把钱投入到开发咨询中,究竟效果如何,不得而知。我想对大多数程序员,尤其是那些有自己想法的程序员来说,请求咨询公司,还不如自己去了解来的清楚。软件开发咨询师在我看来,有点象是"律师"—"代表贪婪的公司,让这个世界变得更糟糕一些"(中 Alex 的对白)。如果说国外的咨询师是希望通过主观的努力来解决客观存在的开发复杂性的话,那么国内的咨询行业可能把原本复杂的软件开发变得更加复杂了。我不相信他们,我宁可选择某个软件的培训,而不希望有人来从头到尾指点你如何开发,因为国内咨询师的水平比你从书本上了解的高不到哪里去,公司又何必花费这笔冤枉钱呢。


那么如果你是个"主动程序员",你会跟着 Sun 的指挥棒走吗? 我想离开 Java 世界,你选择的机会应该很多,但是前提是:你愿不愿意离开 Java 。因为大多数人觉得改变现状其实并不是个好事情,学习一个新语言和框架意为着你过去所有的经验就消失了,这其中有风险。对大多数程序员 来说,编程其实就是份工作,跟卖盒饭,装机器没什么区别,只要搞好本职工作就可以。试图改变现状的人很痛苦,了解差异的人也是如此,就如同 Neo 在接受红药丸和蓝药丸。 我在当年学习 Perl 的时候曾经买过一本《Learning perl》,书的作者曾经这么说,学习 Perl 是为了让自己把更多的时间用在去滑雪, PHP 的创始人 Rasmus Lerdorf 也曾经这样表示过,他希望自己能够减少盯着电脑的时间,可是这么多年过去了,他发现自己还是要继续盯着该死的电脑。其实我对选择框架语言也并没什么兴趣,我只是希望能够以简单的方式完成工作,而把时间省下来去听听音乐,看看电影。实际上我跟不希望改变现状的人没什么不同,他们不希望学习新的东西,因为现有的东西很熟悉了,学习新框架,还不如把时间放到玩上去,我的目的一样,我学习只是希望自己的工作更轻松一点,这样可以用更多的时间来玩。所以每当我看到各种技术论坛上充斥着Java, .net , ROR ,Python 之类的争吵,我都觉得很好笑。其实为了维护一个语言而争吵最没有意义。编程语言就和英语,计算机一样,就是个工具,选择它们只是为了尽可能简单地完成工作,提高生活质量。为了语言而语言,为了框架而框架都是没必要的。"主动程序员"可以选择自己的方式来工作,这是大多数人做不到的。如果有可能,我也希望做一个"主动程序员"。

程序思考:ruby on rails 实践


为什么 Ruby on rails 会在 Java 社区引发轰动,我想原因就在它提供了一个“一站式”面向用户的简单易用的框架,这是 java 框架所缺乏的。为什么 Ruby on rails 能做到这点,难道 java 本身做不到吗? 事实是众多 Java 框架的设计者不这么做,可能是他们的思维已经限制在如何用模式设计一个好的框架上了,而没有在框架的易用性上做更多文章。使用过 Spring 的人就知道它的 xml 配置文件会渐渐的膨胀,虽然我们很容易将其分解为更多的小配置文件来解决这个问题。 但是在使用 xml 配置文件上,它沿袭了 Java 编程的习惯性概念:“Java 是最好的编程语言,XML 是最好的描述数据的语言,两者的结合是最完美的。如果一个应用不使用 xml 来描述,那么它就不是好的 java 应用”。但是 ruby on raiils 就是在这点上和众多 java 框架区别开来,才达到了框架易用性上的一次突破。这个思想贯穿了 Rails 设计的始终:习惯约定优于配置。



本文太长,37页之多。而且CSDN的blog发布机制不好,特地制作成 acrobat pdf 文档,有兴趣学习 ruby on rails 的人,可以下载看看。 估计这是国内写的最详细的一篇关于 ruby on rails 的文档了。




看到我的文档在别的论坛上引起的讨论,我觉得有话要说:


首先,关于ROR的文章引起 Ruby 语言与其他语言的对比,我觉得有点不理解。总是有人喜欢争论语言的长短,正如我在这篇文章中说的那样,我相信将来也不会有什么全能型语言出现,每种语言都有它的长处。我可以用很少几行Ruby代码完成 Java 几十行代码才能完成的功能,那我为什么不用 Ruby 来做呢?是否使用一种语言,对个人来说是“冷暖自知”的事情, 你觉得好你就用,你觉得不好就别用。 我想很多人都看过《程序员修炼之道——从小工到专家》吧,两位作者 Andrew Hunt,David Thomas 就是Pragmatic 编程的创始人,他们用过的语言不可谓不多,最终他们选择了 Ruby 做为自己的开发语言,你能说这种语言没有它的可取之处吗? 不要去做某种语言的“卫道士”,这种做法也不会让你成为它的“创始人”,还是踏踏实实的用好它,如果你喜欢它,就做它的“传教士”吧。



其次,我觉得这个文档引起 Java 程序员的反思要多于实际使用 Rails 的意义,Java 程序员大可不必紧张反应,Java 框架不缺设计模式,不缺好的架构,缺的是易用性。 相信ROR会给以后 Java 框架的发展提供一点新的思路。 我觉得ROR的出现最高兴的人当属 Rubyist (Ruby 爱好者)了,他们从此有了一个 Killer 级的应用, 而之前同为脚本语言的 Python 却拥有让 Rubyist,甚至是 Java 程序员嫉妒的 Zope 系统(Zope 内置 CMS ,Web server 和 WEB 开发方式的确让人惊奇)。而如今 Rubyist 也拥有了这样一个web 开发框架, 而且 ROR 无论在设计思路,性能,开发效率上都可以和 Zope 相比,甚至在某些方面还超过了 Zope. 但是无论怎么热门,Zope 和 ROR 都不会成为主流,影响不到 .net 和 j2ee ,但是他们始终应该在开发领域有一席之地。另外我觉得无论 Ruby, python, perl 如何发展,它们都无法在将来成为主流语言,没有大的商业公司来支持,的确很难,但是它们始终不会被人们忽视的,多种语言的并存才是趋势。



最后,我觉得程序员应该至少掌握一门脚本语言,如论你学 Ruby 还是 Python, Perl 都可以。学这种脚本语言并不需要浪费你太多时间,而且好处多多。多学一门语言能给你另外一种思路,一个视角来看待编程,你的思维也不会局限在一处。我喜欢跟非 Java 程序员混在一起,因为无论是网页设计师还是多媒体程序员,还是 PHP 网页开发人员,他们都能给你新的想法,不象 Java 程序员那样让人觉得闷。从个人感觉来说,如果你是个面向对象的爱好者,那么还是学习 Ruby 吧, 不过 Python 拥有更多成熟的开发库,这些是 Ruby 缺乏的,但是它会逐渐赶上来的。






注:本文章在更新中,不经本人同意,不得转载。下载地址:
ruby on rails 实践