Archive for August, 2004

Gmail 1G邮箱

Saturday, August 21st, 2004

今天上了许久不上的Yahoo 1G邮箱,想到了一些事情。

首先是Google, 然后是Yahoo, 然后是Sina. 这个追逐的背后,真的是扩容那么简单吗?

按照普通用户的用法——我指普通的用户,是通过Email做正常的事情,而不是存贮巨大文件的,一般的用户根本用不到那么大的空间,几十兆足以,因此就可以将空间进行动态分配,你看到自己的邮箱剩余空间永远都剩下1000M – 已经使用的。纵然空间不够了,存储设备也足够廉价,随时买来就是了。

那么,这个1G邮箱真的那么诱人吗?

这么说大小只是其次的东西,Yahoo, Sina或者后续的ISP,只是在抢嚎头。那么大的空间,我想,只有Google的Gmail达到了使用这么大空间的资格。原因很简单,Google拥有世界领先的搜索技术。在Gmail的广告中,有这么一句:don’t delete the email, archive it. 这句话才将大容量邮箱的精髓表达出来。往来那么多的信件,在这么大的存贮空间中,全球这么多的用户,如果没有优秀的搜索技术,1G的空间,除了空间的堆砌,实际上没有什么意义,除非你想把Email邮箱当作下载服务器。不过遗憾的是大多数邮件服务器的下载速度都不是太快,而且服务商也不会太乐意你这么干。

技术学习与假想敌

Thursday, August 19th, 2004

学习久了,做得多了,想得多了,自然就会有点成就了;有了成就就忍不住交流——大虾总是受尊重的,无论在武侠世界还是现实世界;更无论古时与当今。受到的尊重与追捧多了,自然也就有了几分自信。这自信过了头,便是多多少少的自负了。

自负并没有错。自古以来,自负便是英雄和才子的美德,比如吕布,比如司马相如。然而我不能理解的是,一些技术学习者一定要给自己找上一个敌人才肯罢休。这个敌人究竟是不是站在他的对立面尚未定论,他就将对方划入水火不容之境。因此我将这些敌人定义为“假想敌”。这是想象力丰富的表现,也是想象力太丰富的表现。如同矛盾的对立统一,我猜想一旦离开了“假想敌”,这些技术者是否能够有旺盛的斗志继续学习下去。

学习不是吵架。在发情期每一只公鸡看到另外的同性时都会鸡毛耸立示威,如果没有效果则非要咬上一番满地鸡毛才肯罢休。技术者的目的应该更加高尚,更加多样。公平竞争而不是充满感情色彩的技术领域更容易培养和发展技术,反之则如同华山派气宗剑宗分家,结果谁都讨不到好。拥有假想敌固然能够精神抖擞的学习新的技术或者更深层次的理解技术从而羞辱对手,公平竞争开诚布公何尝不能共同进步呢?

有感而发,偶尔撰文,可能文词刻薄,请勿对号入座。

代码生成器的存在价值

Thursday, August 19th, 2004

多年前用ASP的时候,就听说了有一种叫做代码生成器的神奇的东西。只需要指定数据库链接,这个代码生成器就能够产生一个界面,然后选择你需要进行生成的数据表,按一下按钮,马上基于这个表的增删改查界面以及对应的ASP程序代码就生成出来,着实方便。当时的我对ASP已经轻车熟路,看了一眼这个工具后,心中评估了一下,然后使用了一把……看到这个工具生成的ASP程序源代码,让人确实有点接受不了——大小写不区分,大段大段的冗余代码。虽然生成的代码确实能够完成特定的业务操作,但是维护性确实太差了。据说后来有一些优质的代码生成器能够生成更好的程序,但是确实是从那个时候开始,代码生成器在我心里成了垃圾代码堆砌的代名词。我情愿自己编写一行一行代码也不愿意用代码生成器。

现在,当专注于某一个行业,某一种特定业务时,你会发现重复性是如此之大。——用户管理在大多数地方都是类似的,只是用户相对的字段有些不一样;用户登录界面、登出界面可能也是一样的,只是把某些图片换一下而已;大部分的业务操作都是增删改查,对于这种操作不断的采用同一种方式进行重复、还得小心出错;权限管理界面看起来也没什么大的不同……也许我们早就烦了。框架在某种程度上保证了项目的质量,但并不能减少编码量;某些框架甚至需要更多的编码(以及学习时间)。例如,与Servlet+JSP方式相比,Struts除了JSP, 还需要编写特定的Form, Action,并在struts-config.xml中加上几行;Tapestry则需要编写.page, .html, 对应的Page类,如果需要验证还得编写Delegate类;至于FreeMaker,Velocity之类界面工作量可能小了一些,但还得需要编写自己的简单框架用以实现MVC模式。Spring集成了这些表示层,看起来比较好……

上述解决方案的根本问题在于,框架只是保证了项目的质量、可维护性,但是没有减少编码量。因此,代码生成器的使用便是理所当然的了。这方面已经有先例了,最有效、最能够显示代码生成的威力的,当属xdoclet的ejb任务。我们知道,创建一个EJB需要同时创建其他四个无聊的接口,xdoclet在这方面将代码生成的威力发挥到了极致。另外,middlegen也能够创建基于数据库,使用Hibernate, Struts, EJB技术的Web应用程序,他能够生成JSP, Hibernate映射文件,Java类,EJB类等。middlegen应该是我见到的最完整的应用程序生成器的雏形,但是他还不足以具体,不足以缩短编码时间。

我思考了几天,在做OpenBUGZ和公司项目的过程中,想出了这种模型:

基础架构:Spring, Hibernate, Tapestry
Spring,Hibernate的好处自不待言,前台没有采用Struts或者WebWork,是因为前两者在界面表示上不够灵活,Struts需要配合Tiles才能实现灵活的布局,WebWork不太熟悉,不知道如何实现灵活的布局。然而在Tapestry中布局的问题几乎不是问题。

应用技术:Ant, Xdoclet, FreeMaker, JUnit
用FreeMaker而不用Velocity是因为前者有更多的支持,而且从我的使用感觉来说,FreeMaker相对较强大。

开发步骤:
1 首先开发者(项目经理或者技术经理)根据需求对整个系统建模,完成基本类图,生成所有的业务模型类;
2 根据业务模型类编写Hibernate映射文件(用xdoclet可能不太方便,特别是业务模型类存在继承关系时);
3 (代码生成)生成对应的DAO接口例如XXXDAO,用来对XXX对象进行增删改查 (如果采用Spring Hibernate Template,这一步可以省略)
4 (代码生成)生成采用Hibernate的DAO实现
5 (代码生成)生成业务逻辑层代码XXXManager,用来调用DAO层实现各种业务逻辑操作;
6 (代码生成)生成XXXManager对应的单元测试
7 (代码生成)生成业务模型类的增删改查界面Html(通过模板)
8 (代码生成)生成界面对应的Tapestry所需要的.page文件
9 (代码生成)如果需要验证,还需要生成需要的Delegate类
10 (代码生成)生成对应的增删改查Page类
11 (代码配置)在Spring的配置文件中配置DAO的事务
12 (代码配置)在Spring的配置文件中配置XXXManager
13 配置数据库链接,利用Hibernate的SchemaExport直接生成数据库
14 生成整个项目的文件结构,包括build.xml,如果需要,也可以生成JBuilder或者Eclipse项目
15 开发:对 XXXManager进行更改,对界面进行修饰。

从上面可以看到,整个项目工作量已经很低了;-) 这样对业务分析人员的要求比较高,要求一次能够分析全面彻底。项目中最后的工作只剩下修改业务逻辑,修改修改页面了。这就是代码生成器的威力。

MDA,业务其中,技术其次

Wednesday, August 18th, 2004

MDA本意是模型驱动开发,模型自然就是业务模型了,这个描述想当贴切……一切以业务而开始,开发而其次,是业务模型驱动了开发。弄清楚了这一点,就会明白,MDA的思想是方法学的范畴,跟技术关系不是太大。MDA中的关键概念——PIM(平台无关模型)和PSM(平台相关模型),将业务与技术隔离开来。PIM与PSM的概念隔离绝对是有必要的,而并非Intentional Programming(IP)那样,能够将“意图”与代码表现一致就认为万事大吉。(IP中每一个AST(抽象语法树)的节点就是一个元数据模型思路是好的,但是这个元数据的粒度的概念没有MDA中的清晰。所以我认为IP应该只是一个实验室的东东,而不应该会在工业开发中占据一席之地)

若要完全实现MDA的思想,那么最重要最基础的应该是建立一套元数据模型,这一套模型是与实际业务息息相关的,一旦这套模型建立,那么遵循这个标准的所有厂商都会从中获益。用MDA的广告说:遵循MDA思想的系统将”for yestoday, today and tomorrow”.

但是Martin Fowler对此并不感冒。http://martinfowler.com/bliki/ModelDrivenArchitecture.html  我个人的想法也是这样。这种思想可以被很多厂商借鉴,但是是否遵循MDA标准,我持否定态度。在我看来,建立一套模型的成本太高,而且从MDA的思想提出至今,也只有代码生成器一类的东西问世,我所关注的、行业相关的mof模型实在是太少了,更不谈业务规则复杂得要命的如社保系统、财务系统。

JSValidation 1.0b4 released

Tuesday, August 17th, 2004

JSValidation是强大便利的JavaScript客户端验证框架,用以在开发BS系统的过程中,已有开发框架不提供表单验证的情况下,提供一种便利的,易于管理的验证方案。不论你使用ASP/JSP/PHP/Perl或者任何一种脚本语言,JSValidation都可以工作得很好。

感谢各位用户对它的热爱。在收集众多要求的基础上,1.0b4版更加健壮、灵活,实用。简单和实用是JSValidation追求的目标。本次更新如下:

* 修正了以下Bug:
  1) 密码与确认密码在提示时,提示信息为”密码与password必须一致”  (呼声很高 ;-))
  2) 在Mozilla浏览器环境中,对普通ASCII字符判断错误.(严重)
  3) 校验失败后,光标应该停在第一个出错的域中。(普通)
  4) 在IE5.0中完全不能校验(严重)

* 增强了功能:
  1) 增强了多表单的处理,对于新的处理方式稍微麻烦,但是分布式管理的validation-config.xml更能够适合多人协作。
     例如,原来只需要在Html页面顶端引入<script src=”path/to/jsvalidation.js”>,现在除了这种方式,还可以加上
     <script>
           ValidationFramework.init(“validation-config.xml”);
     </script>
     多添这一句使得validation配置文件能够分开存放,在多人项目中非常重要。当然,原有方式继续保留。

  2) doValidate()方法现在更加易用,只需要在需要验证的表单上加入doValidate(this)即可。当然,<form>标记中的ID还是必须有的。

  3) 增强了错误的显示方式。目前可以在form的配置文件中选择是显示全部还是显示第一条。(show-type=”all|first”)
 
  4) 增强了错误的显示效果,可以在validation-framework.js中对ValidationFailCssStyle进行更改。(这个功能不知是否实用)

项目地址:http://cosoft.org.cn/projects/jsvalidation/

论坛:http://cosoft.org.cn/forum/forum.php?forum_id=7008

欢迎使用与反馈。

Keep an eye on your soul of tech.

Monday, August 9th, 2004

Java,开源世界里充满着各种优秀的思想技术方法。这些方法逐渐侵入了我们的大脑,成为左右我们技术选型、程序编码的关键势力。单元测试,敏捷,Struts, Tapestry, IoC(Dependency Injection), AOP, Hibernate…我们阅读,学习,成为大潮中的水滴,如同我一样在J2EE中苦苦挣扎的我们;思考与研究并乐意共享者者成为浪花,如Robin, gigix, Yang,曹晓钢, jdon等等为我们所知。在这么多内外的氛围中,我们像长跑运动员,领跑者为欧美技术领先者,稍后为国内热心的传道士,然后是我等未名之流。奔跑固然痛苦,然而落伍更为悲哀。(扯远了)

古语云,学而不思则惘,不情愿的,我们的大脑越来越像一个容器————因为没有时间思考。成为一个容器是很容易的————哪怕这个容器装满了钻石。没有吸取钻石的精华,永远只是一个装饰与与人炫耀的谈资。但是,就算思索足够,那又如何?只是让自己无知的圆越来越大,并且所有的自己的思考永远都在别人的光辉中。常见到这样的话语:Gavin King提出如何,Martin Fowler又认为怎样。在真正理解他们思想的基础上,我们除了敬仰并添加这些为人神圣的光辉,对于我们个人,实际上一点好处也没有。

我的感觉是,学习成为一个逐渐领悟的过程。这个领悟需要量的积累,需要阅读大量的优秀的作品,需要,按照gigix所说的,学会盲从。所谓厚积而薄发是没有错的。但是有多少沉醉于技术的开发者,真正的”发”了呢?如我一样,成为脑袋里装满了各种最佳实践,每一样代码都能通过Effectiv Java的检验……需要积累没错,但是,请留一只眼睛,给自己的技术灵魂,告诉他,到底需要什么。更多的时候,需要一个撞击,一个大胆的撞击。这个撞击听起来可能像推翻了相对论一样可笑,但是,如果可以,请给这个万马齐喑的技术界一个震撼,并希望这个震撼可以传播到欧洲,北美去。

SOA迷惑

Friday, August 6th, 2004

现代软件的发展过程无不向这几个方面发展:系统分层,模块之间降低耦合,高重用的开发模式和开发成果等。MDA,SOA的出现应该是这一趋势的必然结果,并且SOA必将成为未来的趋势。但是,我对这个宏大的体系架构(情愿称呼它为体系思想,因为暂时没有看到完整应用SOA思想的实例)充满了不解。

什么是SOA? 直译过来就是面向服务的架构。基本概念是基于Web service来编写一个个的服务,然后这些服务可以重用在项目的各个功能中,甚至跨越不同的项目。三四年前,Web Service出现的时候,大量的报道追捧,说以后可能出现一些专门的提供Web Service功能服务的公司,对普通或者专有的服务进行封装并提供接口供调用。然而若干年过去了,这样的公司没有出现,或者没有什么影响力。更多的此方面尝试只停留在实验室中,就连一向前卫的Amaze网站,它提供的Web服务不过是商品的搜索而已。

我的理解:基于WebService的SOA,既然建立在WebService之上,就只能通过提供类似于loginUser(userid, password)(用户登陆)的方法提供给项目的其他模块调用。然而,其它复杂的调用呢?饱含特定业务逻辑的流程呢?也许可以通过BPEL来进行动态配置,并提供对外统一接口。从这个层面上讲,对于业务不包含界面的功能,SOA可以完成得很好(应该说WebService完成得很好)。但是,很多时候,功能是嵌入在特定界面中的。有这样一种场景:

已经完成了一套系统:用户及用户组管理模块。在很多其他的项目中都要用到,数据结构基本一致。按照SOA的功能点,可能有用户添加、删除、更新等方法。对外有类似于addUser, removeUser, updateUser等,为了达到调用这些WebService,客户端需要建立一些界面。建立界面的过程虽然难度不大,但是也有工作量。在各个项目之间,界面的重复工作也在继续。SOA如何将界面也能重用呢?gigix说他们在项目中将CMS嵌入为一个SOA服务,我始终想不通的是,CMS的界面是如何服从SOA的定义被其他项目调用的呢?

每一个项目都有其不同的业务数据模型和工作流程。对这一部分的抽象并重用简直是不可能的。因此,SOA的应用领域仅限于同一个项目或者一个持续集成并可能业务规则不断变化(利用BPEL进行定义)的项目。

XMLHTTP是一种技术吗?

Tuesday, August 3rd, 2004

今天有人在MSN上问我有关XMLHTTP的问题,并问我有关XMLHTTP与Servlet结合的问题。我直接告诉他,直接采用XmlRPC或者Hessian吧。

对于XMLHTTP,我发现很多不了解它的人认为它很神秘。JavaEye上的dlee撰文声称有了XMLHTTP就不用MVC了等等“复杂”的模式,甚至有可能将WEB应用化三层为两层。在我看来,XMLHTTP的引入,仅仅,不过,是改善了用户界面,将原来需要刷新的东西变成不需要刷新而已。这种需求在以前的WEB程序中并不常见,但在现代的应用程序中,随着RIA的思想开始崛起,用户体验变得重要起来,例如:页面无刷新(典型的如树形结构的展开),或者页面的局部刷新。能够完成这项功能的XMLHTTP当然也显得重要起来。

XMLHTTP是一项技术吗?我从来都不这么认为。无论在Mozilla浏览器,还是在IE,他的方法/属性就那么几个:open, send, onreadystatechage, responseText, responseXML……这么抽象的东西,完成了原来浏览器的发送请求/接受数据的请求。这么看来,XMLHTTP不过是浏览器的一个附属线程而已。你可以用它实现你想要得无刷新等等一系列效果,那是有条件的:

这个条件就是,在没有XMLHTTP之前和之后,你的代码都不会因此而减少,更多的情况是代码增多。对于简单的应用,例如用户登陆,像服务器提交用户名密码,返回一个true或者false来代表登录成功与否。有了XMLHTTP之后,这个登陆效果可以做得很眩,同时代码跟没有XMLHTTP之前差不多。但是对于复杂的应用,例如大数据的列表,那么你有如下几种选择来使用XMLHTTP:

1 对于懒人,最简单的方法莫过于在服务器端将列表的HTML生成(大段的<tr><td>之类),然后输出。客户端用xmlhttp.responseText,将数据取得。一眼便知,这种方式除了界面无刷新,代码量,难度等等不会有多大的变化。

2 对于喜欢XML或者喜欢结构化数据的人,会将数据包装成为xml节点,然后在客户端用xmlhttp.responseXML取得XML。然后就有两种处理了:在我看来,最简单的处理就是写一个XSL对取得的XML进行解析然后显示,最笨的方法当然是自己解析XML节点树,然后进行处理并显示了。附带提一句,我在做一个OLAP系统的前台展示,就是用的前一种方法。因为OLAP系统的分析结果的XML形式固定。

3 对于基于命令的系统或者命令有限或者规则简单的系统,可以自行设计一套消息格式,在客户端与服务器端之间进行“编码->发送请求->解码->处理->发送结果“的游戏。这种玩法是我的LIVECHAT场景聊天室中采取的方式。这里面比较麻烦的是设计消息格式以及服务器端的编码、解码处理。如果可以,建议采用XMLRPC来实现。

也许还有其他方式的应用,我没有涉及到。但是,无论哪种方式,我们都可以看到,这些操作仅仅是前台表现层面的。对于业务逻辑,数据访问,权限控制等等,XMLHTTP有办法处理吗?

XMLHTTP仅仅是一种方式,一种无刷新与服务器进行交互的方式。他能够很大程度的改善web application的用户体验(而不是开发模式,更不谈开发效率)。实际上,在普通的web系统中采取xmlhttp是完全可行的,但是在需要实时操作的项目中(例如我的LiveChat),xmlhttp并不一定是最好的选择。因为创建一个xmlhttp/xmldom对象的开销比较大,假定每隔一秒向服务器发送消息,并用XMLDOM处理返回的xml节点,客户端不一定都能承受。我试着做了一些缓冲池,但是在IE环境下表现并不出色。