2005年3月1日
这将是在这个站点(webuc.net/mechiland)的最后一篇blog, 新的blog搬家到
http://michael.nona.name
原有的blog已经迁移到新的blog. 本blog将不再更新,感谢各位的支持!
2005年1月28日
从Howard的Blog上得到的消息,改善了XSLT的HiveDoc已经比较漂亮了:
http://jakarta.apache.org/hivemind/hivedocs/index.html
但是,遗憾的是,就是这种界面也不觉得有多漂亮。我在HiveMind初探中提及,HiveDoc是Hivemind比Spring有优势的地方之一,这种优势已经不复存在,BeanDoc生成了更漂亮的文档,相比HiveDoc而言,BeanDoc在组件之间的关系上进行了更清晰的描述。
BeanDoc描述的JPetStore: http://springframework.sourceforge.net/beandoc/jpetstore/
petClinic: http://springframework.sourceforge.net/beandoc/petclinic/
2005年1月21日
| Echo | Cocoon | Millstone | OXF |
| Struts | SOFIA | Tapestry | WebWork |
| RIFE | Spring MVC | Canyamo | Maverick |
| JPublish | JATO | Folium | Jucas |
| Verge | Niggle | Bishop | Barracuda |
| Action Framework | Shocks | TeaServlet | wingS |
| Expresso | Bento | jStatemachine | jZonic |
| OpenEmcee | Turbine | Scope | Warfare |
| JWAA | Jaffa | Jacquard | Macaw |
| Smile | MyFaces | Chiba | JBanana |
| Jeenius | JWarp | Genie | Melati |
| Dovetail | Cameleon | JFormular | Xoplon |
| Japple | Helma | Dinamica | WebOnSwing |
| Nacho | Cassandra | Baritus | |
2005年1月19日
Bindows(http://www.bindows.net)新版本1.30beta出来了,增加了千呼万唤的Theme支持。Erik&Emil不愧为世界水平的JavaScript高手,原本仅用做浏览器脚本支持的这个小东西如今被发挥得淋漓尽致,几乎到了浏览器JavaScript所能表现的最高境界。看过的人几乎都会叹为观止。观止观止,观而止,这一点上,客户似乎与开发者保持同样的态度。
无论从Bindows的站点,还是其论坛,还是Google的搜索结果,对Bindows的感觉几乎停留在这样一个感觉层次:技术好,速度慢,至今没有商业案例。更有甚者,评价其为“C/S的回归”。回归意味着什么?对于开发者而言——呃,我一直将开发者置于比客户低的地位——,除了恢复原来的编程概念、方法、模式,照拿工资,几乎没有什么改变。技术的变革从来不是以开发者的利益作为第一位的。而对于客户,这种回归却是不可接受的。
ChinaUI(http://www.chinaui.com)上每天都有新的设计作品产生,有相当大的数量集中在B/S系统的产品上。B/S给软件开发带来巨大改变,但与此同时进行改变的是用户的审美品位的提高。你无法再将windows经典的窗体颜色应用到绝大多数Web应用中,美工开始变得重要。客户口味越来越奇怪,很多时候一个项目的交付被卡在美工上,客户喋喋不休的说这个颜色/那个颜色不喜欢。从国内外已经出现的软件界面设计公司,可以看到这样一个趋势:用户对软件的需求已经不仅仅满足于实现功能,对软件的体验开始变得同样重要。回忆一下,《冒牌天神》中发邮件的界面,一些电影中显示人员档案的界面,《黑衣人》中的海关电脑界面。随着软件的发展,这些界面相信也会出现在实际的软件中。
RIA应运而生。Macromedia公司的Flex(http://www.macromedia.com/software/flex),开源的Leszlo(http://www.openlaszlo.org),都是这方面的代表。Flash经过多年的发展,已经从典型的动画格式开始向着一种用户友好的表现形式发展。从Macromedia官方公布的资料看来,已经有一些成功的商业应用采用了Flex,用户体验相当好。而从我给一些客户演示laszlo的实例来看,Laszlo“增加了对Web应用的期待”。这种期待显然是界面、操作感觉的期待。RIA, Rich Internet Application, 在我看来一个最为体贴的解释就是“丰富客户体验的Web应用”。Rich在这里,所指并不仅仅是提供开发者丰富的控件,更重要的是给客户丰富友好的体验。
Bindows所做的,从第一眼看上去,就象是所有windows控件的模拟。按钮,标签,列表,文本框,对话框,颜色,样式,等等,一个典型桌面应用应该有的控件、样式都具备了。客观的说,用JavaScript实现这些并不容易,作者花了整整两年时间,这个产品还在继续维护。为什么至今没有商业应用(据我所了解,没有)愿意采用Bindows呢?我分析:Bindows不能成功也不会成功的根本原因在于,它意味着用户体验的倒退。换句话说,这是一个开发人员一厢情愿的产品,丝毫没有考虑到用户操作感觉。如果这是一个彻底的桌面程序框架,融入到传统桌面程序的大潮中,那么也许还有成功的可能;但是这个产品定位于运行在浏览器中,是Web程序,没有用户愿意看着别人能够在浏览器里进行丰富多彩的操作,而自己只能对着灰蒙蒙的屏幕。当然,在我所未知特定行业里面或者用户操作计算机层次不高的情况下,用户体验也许不重要;但是随着时间的发展,这一点会逐渐消除。毕竟,没有人会拒绝美丽。
2005年1月18日
除非是内容相关的系统,如CMS, Blog, 新闻,门户,论坛,网站系统等,这些系统需要一个明确的链接,来指引用户进行直接有效的访问。但是企业应用系统往往对这些并不关心。例如一个信息管理系统,几乎没有人关心浏览器地址栏里面的链接组织形式,除非一些别有用心的用户。
把握这一点很重要——我是指进行一个Amowa的实现。在我去年提出观点中,我指出,amowa不适合内容相关的系统。虽然这么说,但是当我试图实现一个amowa思想的论坛时,URL相关的东西让我头痛不已。一方面,既然是改善客户体验,所有的操作采取无刷新的方式来进行,那么用户从浏览器中看到的就只有一个地址;而另一方面,用户也许需要对某一贴进行引用转贴时,需要知道类似与thread?id=123的东东。这个问题困扰了我很久,项目也迟迟未动工。
在参与现在的这个商业项目中,我注意到用户根本不关心链接的组织形式,特别是系统非常庞大,页面采用框架进行组织时,浏览器中地址从来都只有一个。操作的感觉就像原来的VB/Delphi时代的C/S软件一样。这么说来,对于操作/功能型的系统,URL并不重要,那么这个时候amowa的各种威力就发挥出来了。
下面附上这段时间思考的Amowa框架目标,希望对有志于amowa框架开发的同仁有些启发:
- 采用纯粹HTML作为界面描述语言,减少学习梯度。只要学习HTML便可编写WEB界面。
- 利用XMLHTTP或者其他访问方式来进行远程访问/调用,减少带宽要求
- 一致性对待客户端与服务器端。对页面开发者而言,他看不到服务器端;对服务器端而言,他看不到客户端。两者完完全全的独立开来。
- 服务器端控制页面流转,非常简单的方式进行页面跳转,客户端被翻译为正确的JavaScript调用,从而让客户感觉更好。
- 客户端缓存。客户端访问得来的页面内容,被缓存到客户端,下次访问非常非常快。
- 丰富的客户端组件
2004年12月30日
StarCraft游戏初期,神族高级玩家一般喜欢在出了一两个狂热者就带上一个农民出发,利用优秀的微操作能力很可能推倒一些心理素质不太好的Player,尤其是对付虫族的小狗,如果操作得当,两个狂热者往往可以消灭掉6~8个小狗。然而这一战略如果用过了头,比如,在刺蛇海面前,再优秀的微操作马上变得可笑。在一次国内的比赛中,我曾经看到过这样一场悲壮的比赛。
有一句话说得很对:先做正确的事,然后正确地做事。如果把大型项目比喻为刺蛇海,那么我们无论如何都不能在这样庞大的攻势面前傻乎乎的用某一两个“设计模式”、“PoEAA”或者“Core J2EE Patterns”这样的微操作。原因很简单,在业务架构尚不清晰的情况下,盲目的用小规模的技术组件来套用是愚蠢的做法。我经常听到不成熟的程序员这么在说:晤,这里可以用状态模式,嗯,那里可以用解释器模式。问问他是否真正明白业务的需求,他一脸茫然。当目标从一开始就错误的时候,再优雅的设计得到的顶多是一堆优雅的垃圾。
那么,正确的事是什么?是正确评估分析你的业务。业务架构是技术架构的基础,业务语义是技术语义存在的前提。这个问题之所以没有被得到重视,是因为我们现在做的大多数系统都还比较简单,我以前做过的项目基本上用事务脚本便可以解决,通过数据库的增删改查从而完成特定功能;在此基础之上建立了一系列技术组件,比如OA, 工作流,CMS。在分析项目的时候,将功能需求往已有的技术组件上套,然后用不太先进的技术完成了一个又一个的项目。因此我说,项目成功的保证一定不是所采用的技术,而是对业务的理解程度。
我们比较不幸。客户越来越成熟,对信息系统所能带来的生产力期望值越来越高(政府项目除外)。大量的旧的系统如电力,金融等,开始被迁移到J2EE平台。J2EE平台技术的成熟并不等同于业务的成熟,当一个系统膨胀到刺蛇海的规模时,当功能需求书堆起来一米多厚、功能错落有致、交叉相连时、就是这样也不足以描述需求时,那么技术方面的某些小小的微操作、模式就像是刺蛇海面前可怜的狂热者,潇洒却凄凉;又如同印尼海啸面前“坚固”的漂亮的海边别墅,不堪一击。在对这样大的项目进行分析的时候,业务是最重要的。将业务分析清楚才是正确的事,而不是上来就往J2EE N层模式上套。放之四海皆准的方案,往往可行性、操作性成问题。只有当业务分析清楚了,业务功能之间的联系也分析清楚了,怎么做就变成了很简单的事情:无论你怎么做,代码写的多么难看,只要完成功能,你做的事情都决不是Dirty work.
然而,业务分析也太艰难:当你面对一个具有十几个子系统、几千种交易、数百种工作流、子系统功能之间纵横交错的时候,没有业务知识和技术知识的双重修炼,这件事情无异于mission impossible. 这方面,我想才是自己需要修炼的一个方向。Raimundo同志正在进行这方面的研究,希望能够有所建树。
稍微有点高兴的是,目前我们接触到的项目大部分并不庞大,大部分都能够进行归类,比如简单的业务逻辑普通的增删改查就能完成,复杂一些的加上工作流支持;大一些的公司有能力对这些操作进行积累,称之为“技术组件”,因此某些以构件为核心的解决方案(公司)抢到了许多订单。从一段时间趋势来看,这种方式也是目前最可行的一种方式。
2004年12月22日
深入开源世界的程序员的思维大多发散严重,这种发散在很多情况下是有害的。在制作一个新的产品/项目之前,很多人都会说,唔,你应该参考好的开源东西,把他直接使用。殊不知这样拿来就用伤害最大:因为自己根本没有机会仔细思考自己要做的东西是什么样子的。这就是Hibernate之所以创建EHCache的原因。在EHCache之前,已经有不少Cache实现,为什么没有直接使用?因为Hibernate自己都不知道Cache接口应该是什么样的。因此有了小小的简陋的EHCache, 正是有了这个小小的东西,其他Cache机制的集成才成为可能。因为Hibernate知道与外界集成要遵循的接口是什么。如果当初直接采用某一种Cache实现,恐怕就没有了现在灵活的Cache机制了。
(这种思维的方式同样可以推广,为什么小公司不愿意接受数额较大的融资,因为这样很容易将小公司原本不太清晰的发展观念冲垮,最后什么也不是。)
现在设计平台,发现陷入了这样一个怪圈:我总想将最新最好的开源产品集成到平台中,却忽略了Roadmap Feature的定义,也就是说,没有一个清晰的标尺来定义平台某一个版本应该包含那些特征,应该达到什么效果。这样做的后果是我陷入在一个又一个优秀的产品中,像上瘾的烟鬼拔不出来。在深邃的开源世界里,一切的一切都太又诱惑了:为了选定一种O/R映射方案,我比较了JDO的各种实现以及Hibernate,阅读了大量文档(广告?),最后还是回归到Hibernate; 为了选定一种Mock测试方案,我比较了EasyMock, jMock, 之前我从未用过Mock测试,现在我对EasyMock的机制已经相当清楚了;为了选定一种代码覆盖率工具,我比较了Clover, Jcoverage和Emma,最后选定了Jcoverage, 为了选择一种IoC容器,我比较了Spring和 HiveMind,最后选定Spring, 为了选定一种Web开发框架,我重新审视并比较了SpringMVC, WebWork, Struts, Tapestry.,最后选定了Tapestry。这个过程充满了感叹,也充满了诱惑性:很多具有相关性设计精美的项目会时不时招摇的在你眼前晃来晃去,让你忍不住看下去,然后你一个下午的光阴就耗费在从Google或者TSS或者JavaLobby一个链接开始而引入的一个深渊,留下你无法弥补的4个小时的时间。看着越来越近的Release Date, 心情越来越不爽。
因此,一旦前期调研结束,程序员应当果断的将与开源的联系一举切断,专心致志的投入到实现中去,一旦发现有可能抠出新的设计的地方,不要马上就找开源的产品,请先用自己的智慧设计一个能用哪怕是破败不堪的(好的设计是重构出来的,不是吗?)东西,先将框架搭建出来,一个迭代过后,开始重构,等到这个设计基本成型了,能够运行了,然后重新获得与OS的联系,参考同类产品,进行重构或者集成。这么做的目标是控制住发散的思维,在有限的时间内拿出一个在当前状态下最好的方案与实现,没有底线的项目/产品是个毫无意义的泡泡,脆弱,除了作为夸夸的谈资,经不起明眼人的一锥子。
2004年12月7日
经过漫长的商务折磨,终于确定了自己平台规划负责人的角色,任务非常明确:采用开源技术进行组装,开发一个具备业务含义、能够进行快速开发的软件平台。
现有项目的运行情况让我认识到了一点:在持久层与业务逻辑的相对成熟的情况下,WEB层的工作最为繁重,哪怕是引入了Tiles改善布局也如此。Struts天生的缺陷,让整个项目中WEB层显得笨拙不堪,成为整个系统中bad smell最重的的区域。从软件技术大会回来的同事说,很多同行都认为B/S系统中WEB端的工作量是整个系统的瓶颈。这一点看来已经得到了业界的普遍认可。
而现有的这个平台一定是持续使用的。如果不在WEB开发上进行改善,那么这个平台显得毫无意义:在依托面向对象技术的Java平台下,大部分其它的东西都有现成并且健壮的,对我而言都是熟悉的;而在WEB层,一定要有一个具备重用、珍惜每一个可重用WEB组件的框架在支撑。由于我们这个行业的特殊性,再带宽上也应当有所考虑。
基于这些特征,我首先想到的就是面向组件的WEB框架。这里的组件一定是网页上可见的组件,能够天生穿透Java/Javascript/Html,而不是笨拙的在JSP中import javascript;或者采用不堪的JSP tag. 这么看来,具备这一特征的、成熟的框架只有Tapestry了。
然而我对tapestry还有所保留,原因有两点:一个是对大型系统的支持不足。我们要面临的系统达到十几个子系统,3000多种交易。而Tapestry模块的支持区分不足,这一点上,WebWork来的要自然的多,Struts也提供了支持(我实在是难以出口这个词,虽然Struts将我引入了MVC的门,但是我对其丑陋的设计,臃肿的配置文件充满了憎恶)。
第二是Tapestry难以理解的URL,总让人觉得诡异(刚开始觉得挺有意思),不便于书签。好在有成功的项目证明进行修改是可行的,这个工作量也应该不大。
如果我的AMOWA概念有实现,那么我一定会选择Amowa的实现。因为Amowa中异步的概念刚好满足了系统带宽的要求。Web框架的选择过程让我了解到,组件式的web框架在知识积累上有多么重要。试问一下,我们以前做的WEB应用中,web端有多少能够自如的重用?
纵然Tapestry不尽人意,我还是决定选择Tapestry来作为平台的WEB框架(有人会说Tapestry不便于测试,试问又有多少合理的项目会将业务逻辑写在XXXPage中?),对其进行一些改造是必需的,比起持续使用与知识积累带来的好处,这么点工作量算不了什么。
2004年11月20日
昨晚开始了痛苦的历程。
一向工作得好好的xdoclet,自从我将核心包更新为1.2.2后,噩梦开始了。每次运行hibernatedoclet, 都会出现以下错误:
java.lang.NoSuchMethodError: xjavadoc.XJavaDoc.setDocEncoding(Ljava/lang/String;
)V
at xdoclet.XmlSubTask.startProcess(XmlSubTask.java:184)
at xdoclet.modules.hibernate.HibernateSubTask.execute(HibernateSubTask.j
ava:123)
at xdoclet.XDocletMain.start(XDocletMain.java:48)
at xdoclet.DocletTask.start(DocletTask.java:468)
at xjavadoc.ant.XJavadocTask.execute(XJavadocTask.java:96)
at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:275)
at org.apache.tools.ant.Task.perform(Task.java:364)
at org.apache.tools.ant.Target.execute(Target.java:341)
at org.apache.tools.ant.Target.performTasks(Target.java:369)
at org.apache.tools.ant.Project.executeTarget(Project.java:1214)
at org.apache.tools.ant.Project.executeTargets(Project.java:1062)
at org.apache.tools.ant.Main.runBuild(Main.java:673)
at org.apache.tools.ant.Main.startAnt(Main.java:188)
at org.apache.tools.ant.launch.Launcher.run(Launcher.java:196)
at org.apache.tools.ant.launch.Launcher.main(Launcher.java:55)
无法生成hibernate配置文件
没有源码,反编译找到XmlSubTask,没发现什么问题;找到xjavadoc相关的类,setDocEncoding赫然存在。
Google了一下,只有两条纪录,也没有解决,只是说注意版本。我试着将所有xdoclet jar文件换成1.2b4, 再次ant...居然成功了!郁闷,然后依次将hibernate, web相关的jar更新为1.2.2,没问题;就在更新xdoclet.jar之后,出现了上面提到的那个错误。
问题很明显了,是最新版本的问题。具体原因不祥。还是老老实实用旧版本吧。
2004年11月16日
许多Blog开始沉寂下来,这应该是一件好事。目前积攒的能量大概已经释放的差不多了罢,否则我的FeedDemon上为何迟迟不见重量级的文案,只有些 许简单的文档零星散落,让人感受到了这个冬季依然存有活物。当然,昨日黑今日白的娱乐圈新闻不在此列,Intel与AMD永远的口水战及其记者壁垒也不在 此列,更不提永远看不到尽头的在伊拉克的美国大兵。
Blog诞生初期那一阵子引发了众多英雄的诞生。由于交流渠道的扩充,每个人的技术能力在一夜之间被暴露出来,技术圈内Blog迅速成为交流技术思维的工 具,如同百晓生的兵器谱,每个人的心里对Blog的优劣有了一个明显或者隐藏的排名。然而早期的激情与自己的能力在被释放之后,Blog歇了下来。 Blogger们,如同我自己,开始担心,如果Blog很长时间没有东西更新,会不会如同被抛弃的孩子被人遗忘。巅峰到低谷的感觉很难受,于是出现了我前 面Blog提到的"
口水文字", 这些文字就像想引起女生注意的男孩做的恶作剧,单纯得可爱,单纯的令人心碎。
电视中,电影中时常会有脱衣的表演。我想到一个非常悲凉的比喻,技术人通过Blog表达自己思想的过程就像表演脱衣舞。每传达了一个思想就脱掉了一件衣 服。思想的深度和广度表示了衣服的华丽程度,从而引起观众更多的惊叹。高明的舞者总能在一个适当的时间内将衣服脱到适当然后谢幕,引起观众的美感与期待; 而不太高明的技术者往往迫不及待的在不太长的时间内将自己脱个精光,或者匆匆躲进后幕,换一件更为破烂不堪的衣服出来表演。
Martin Fowler的网站访问量巨大,他的著作遍及世界,被众多读者品读。他二十余年软件行业的积累,通过每年一两本书或者几个月一篇文章的方式释放出来,观众 看到的是一个高明的舞者,一个让人追逐让人陶醉的舞者。很多事情,特别是技术上,需要太久太久的积累,过早的不适当的释放,就像《赤旗寰球记》中“亿万民 主投票拳”,满天胡打但不中要害。百年的酒耐人寻味,多年的积累让人承认才有成就感,来得快的东西,去得也不慢。
最后,以我自创的一句话结束:你是否拥有让众人传唱千年的裸体?如果不是,请不要跳脱衣舞。
2004年11月15日
前言:
本文的源自于Martin Fowler的著作《Patterns of Enterprise Application Architecture》中关于Web表示模式的一些启发。作者做了多年Web开发,并不限于企业级Web应用。在娱乐方面的应用(如聊天室,即时消息,Web场景聊天等)得到的一些工作经验促使我在企业级应用上进行了深层次的探索和思考,并形成了这篇文章。目前国内外并没有明显在这方面的文章或著作,希望此文能够给做WEB开发的同仁一点借鉴之处。
本文的最先在2004年11月13日的javaparty聚会上以PPT提出,后经过整理完成。
1 观点提出
标准的遵循HTTP GET/POST的WEB开发方式往往遵循这样一个流程:客户端发送一个请求:GET或者POST给WEB服务器,WEB服务器处理完成后将结果以Response返回给客户端。在得到服务器的响应之前,客户端一直在等待,页面停滞,用户将看见浏览器长长的的等待条慢慢增长。
而Google Gmail给了我们完全不同的体验。你无法感受到页面的跳转,系统反应非常快。获取新邮件不需要手动或者自动的刷新浏览器。这一切给人的感觉是那么友好,以至于它一经推出便得到了众多用户的宠爱,并同时成为Sina,Yahoo等邮件提供商的追赶对象。
这便是我要提出的面向异步消息的WEB应用(Asynchronous-Messaging Oriented Web Application, 简称AMOWA)的一个小例子。一个具备AMOWA特征的WEB应用具备以下三条:
1. 系统必须是一个WEB应用。事实上,在非WEB环境中设计与实现异步调用非常简单,考虑也很自然。但在WEB环境下,设计与实现相对比较麻烦,思维方式也稍微会有些跳跃感。
2. 系统中必须具备消息特征,无论是隐式或者显式。在网络游戏,即时消息工具等应用中,消息特征比较明显,这方面的论述也比较多;但有些企业应用,也能够发现一些隐含的消息模式。比如,一个商业智能WEB客户端,需要进行钻取、上溯、切片等操作,这些操作和返回值可以被包装为消息(事实上,目前已经有相关的规范,分别是MDX和XML/A);在操作型WEB应用中,操作同样可以被抽象为消息,比如一个Bug管理系统,提交Bug, 查看Bug等,都可以包装为消息。
3. 消息必须是异步的。这一点是与传统方式的根本不同之处。传统的方式在完成某个操作一定存在页面切换,而AMOWA不必。消息是异步传输,在操作完成之前客户可以看到一个友好的Loading或者其他友好的提示,等到操作完成数据可用之后,前台的UI采用javascript/Flash的方式进行刷新。
2 AMOWA的出生历程
AMOWA的提出来自于网页出现的这十多年。
最初始阶段传统的聊天室。前台网页往往需要经过几秒钟自动刷新一次来获取其他在线用户的发言。后来出现了无刷新聊天室,或多或少采用了隐藏帧来处理消息的定时收发。在这期间出现了Pushlet, 一种意图将HTTP消息"推"到客户端而不是客户端主动"拉"的方式。这种方式在客户端看来,就像是一个有一个永远也下载不完的页面;服务器端往往不允许buffer, 并通过response.write然后直接response.flush的方式向客户端写数据。
之后的一段时间WEB应用一直停留在标准的Request/Response的方式很久,直到XMLHTTP的出现,面向异步消息的应用才多了起来,同时由于思维方式的扩展,很多采用同样思维的应用也出现了,这些应用跨越了很多行业,包括商用和娱乐行业,直到现在,面向异步消息的WEB应用已经能够成功胜任大多数的WEB应用,并以改善用户体验为最终目标,越来越受到重视。
3 应用场景
商用领域,包括但不限于
l 邮件应用程序。这一点,在Gmail上已经得到验证。邮件应用是最典型的异步、消息的应用,在WEB环境下,异步消息模式完全有理由应用在邮件系统客户端中。如果有一种方式能够让你不刷新就能够获取新邮件,让你不需切换页面就能够阅读/编写邮件,你还会想回到老路上吗?
2 即时消息应用。典型的无外乎MSN Web Messenger. 即时消息并不要求实时性。在即时消息系统中,延迟2~3秒用户是完全符合用户期待。而这宝贵的2~3秒给了即时消息的WEB应用提供了生存空间,并给了即时消息服务提供商新的卖点。
3 商业智能客户端。商业智能产品越来越趋向于WEB--或许这是整个世界应用的发展趋势;WEB上对数据立方的钻取、旋转、切片如果需要切换页面,没有多少人会很愉快的接受这样的系统。这样需要频繁操作的系统,AMOWA是当仁不二的选择。
4 WEB地图系统。www.go2map.com 上的地图,大家可以看到异步操作模式下的地图是多么自然;相反,ICQ提供的地图服务让人难以接受:每次点击或者圈选地图之后,就要等待一段时间的白屏。
5 其它操作性强的系统。比如,财务信息管理系统,前面提到的Bug管理系统,具备明显或者能够抽象成命令特征的系统。注意,国内政府或者大型国企需要的OA等项目不太适合应用AMOWA,原因是大多数情况下,消息格式的定义比起需求的控制、界面的变更以及项目完成后的使用率,显得微不足道且毫无意义。
娱乐与游戏领域,包括但不限于:
l 聊天室。没有什么比一边聊天一边听着浏览器自动刷新时发出的"叭哒"声更讨厌了。更加细心的定义AMOWA的消息结构,你会发现聊天室的访问者更多了。
2 WEB在线游戏。不要以为不可能,请访问www.51js.com, 那里有令很多传统WEB开发者意想不到的东西。目前已经实现的有:LiveChatV2, 一个纯JavaScript+HTML的场景聊天室;中国象棋,纯JavaScript+HTML的网络版中国象棋。目前台湾有一款真正的WEB网络即时战略游戏,正在线运营,月卡好几十台币。
当然,由于异步消息的限制,WEB在线游戏不可能做到实时,因此目前WEB网游被限制在消息实时性要求不高的领域,如棋牌,社区,简单的网络游戏。3 其它。
4 优点
4.1 从用户来看:
1. 更好的用户体验。
很多高级用户不愿意听到浏览器刷新发出的声音。这个用户群体在扩大。在现代的企业级WEB应用中,经常有及时消息传递的要求;让他们听到刷新的声音是不合适的。AMOWA的引入将彻底无刷新,用户感觉更好。
2. 更好的用户体验
对用户而言,单页面的操作更为友好。大部分用户对于切换页面时那段漫长的时光感到度日如年,并且感到不自然。在商业智能/报表这样的操作中,单页面操作显得格外重要。
3. 更好的用户体验
等待的页面更为友好。在操作得到数据返回之前,用户将看到的不是白屏和长长的浏览器状态条,取而代之更为友好的提示和状态条。对于高级用户,这样的改变将令他们惊喜。
4….呃,更好的用户体验
由于系统中传递的是纯粹的数据,对用户而言,系统显得比普通的应用更快了,感觉当然更好。
4.2 技术观点
1. 在某些场景下,客户端可以是纯粹的HTML, 而不是讨厌的JSP Tag, 或者Tapestry难以理解的jwcid(实际上一点也不难理解^_^), 或者Struts那恐怖的tag, 或者毫无IDE工具支持的JSF。业务逻辑、服务器端特定语言特征与客户端彻底分开。美工可以真正安心的做页面。
2. 服务器端可以进行一些有趣的设计,例如任务队列。由于客户端发送来的是消息,服务器端可以将发送来的消息按照队列来进行处理,而不用马上响应。
3. 容易实现分布式部署。由于客户端与服务器端的完全分离,服务器端的分布、状态迁移、Cache共享将不成为问题。
5 基于AMOWA的设计
基于AMOWA的设计将分为两个部分:面向企业级典型WEB应用和面向娱乐游戏的典型WEB应用。
5.1 面向企业级典型WEB应用
基本原则:一个典型的企业级WEB应用一定是一个分层结构、设计良好的应用。分层设计意味着数据层,业务逻辑层与表示层能够清晰的分开。
AMOWA专著于WEB表示层,它连接了系统的业务逻辑与前端WEB页面。AMOWA Gateway负责解析前台发送来的消息包,将消息包解析为相应的业务操作,调用业务逻辑操作,将操作结果进行序列化,封包为消息,发送给客户端。
客户端有一个客户端引擎,能够接收、解析消息包,并根据消息内容,对UI进行刷新。这里的刷新可能对应一个javascript脚本,也可能对应一个Flash的action script脚本。
AMOWA定位在与Struts, WebWork, Tapestry等WEB框架的同一个层次上,并能够取代他们。
下图表示了这种架构:
这种WEB应用在AMOWA看来,具备最大的特征是:各个会话之间的交互较少。在下面的面向娱乐游戏的AMOWA设计中,会话之间的交互显得格外重要。
5.2 面向娱乐游戏的AMOWA设计
面向娱乐的AMOWA与面向企业WEB应用的根本不同在于,前者会话交互需求较高,比如在一个网络游戏中,经常需要知道另一个在线玩家的当前状态,因此,在这种设计中存在一个中央context来保存这些信息,来保证在线操作者之间的交互。基本设计图如下:

Context连接了基本的底层设施--比如,保存玩家经验值,扣点等。
6 实现
以下是一个AMOWA接口的伪代码
* 客户端将操作包装成消息并发送:
clientOperation.sendMessageBundle(msgBundle, callback);
callback定义了消息的处理策略。
* AMOWA Gateway负责获取前台发送的消息,并处理
messageBundle = buildMessage(request); //将Request包装成MessageBundle
returnedMSGBundle = process(messageBundle); // 处理消息包
sendReturnedBundle(returnedMSGBundle ); //发送处理结果
* 在process方法内部,简单的调用业务逻辑层的处理方式:
bizDTO = bizService.doSomething();
return bizDTO;
AMOWA Engine将会将bizDTO序列化为系统能够辨认的消息格式,生成消息包。
以上的实现相对简略,实际上,设计这样的一个AMOWA Framework技术上不是太难的。如果想偷懒,XML-RPC的实现可以直接拿来使用。XML-RPC在几乎所有语言上都有实现。
7 相关技术
客户端技术:
DHTML, JavaScript
我在文中偏向于这两点,是因为我对这两种技术相对较熟悉,实际上Flash更适合用来做前台表现。当然,前台用何种技术并不影响AMOWA的架构方式。AMOWA定义了客户机于服务器之间的一种通信方式,而并非客户端实现方式。
服务器端技术:
任意一种服务器端技术都是可以的。然而,具备面向对象特征的服务器端技术在实现上能够更自由、合理一些。那些老式的服务器端技术如ASP,想要实现一个AMOWA Framework显得较为困难,这一点在设计WEB网络游戏时显得格外突出。
XML-Binding的技术一定是需要的,无论是客户端或者是服务器端。这是由于我们的消息格时往往用XML的方式来定义。在服务器端返回对象时,能够直接序列化为XML将会给消息的包装带来便利之处;客户端若能够将HTML或者Flash某个控件直接与XML一个节点或者属性进行绑定,那么前台的工作量将会更少。鉴于服务器端的XML绑定已经有很多不同的实现,如JAXB, Castor, JiBX等,笔者最近在试图无浏览器差别的将XML对象绑定到HTML元素上。
选择一种消息传输协议是必要的。目前有两种选择:Web-Service和XML-RPC。在现有系统的消息特征明确并且不太可能会将每个方法暴露给外界的前提下,Web-Service是最不推荐的选择。Web-Service冗余的信息太多,传输或解析都会带来时间和带宽损耗。如果没有时间定义消息格式,那么XML-RPC将是一种比较好的选择。他对数据类型进行了较好的包装,对于WEB应用足够,并且有足够多的语言实现支持,客户端和服务器端都有。
如果时间足够,最好能够自行定义消息结构,和编码、解码方法。这并不是很复杂的事情。这样编码的消息能够以最小的带宽损耗进行传输。这一点,在带宽有限制的应用中显得格外重要,例如银行的业务系统。
8 相关问答
问:AMOWA与RIA有什么关系?
答:没有关系。AMOWA定义了WEB应用一种新型的交互方式--采用消息方式。RIA可以是AMOWA客户端的一种实现,AMOWA的客户端实现可以是Flash, XUL, 或者HTML.
问:AMOWA与XMLHTTP的关系?
答:XMLHTTP是AMOWA实现无刷新、异步消息的一种手段。目前只有这样一种手段来获得异步连接。其他方式如动态加载远程javascript, 动态加载远程网页,多少是同步的方式,会导致客户端浏览器的瞬间不可用。
问:AMOWA有没有实现?
答:暂时没有。我正在编写一个,主要面向在线游戏。但是由于工作繁忙,进展缓慢。基本思想如同上面的描述,有兴趣的同仁可以自行实现,造福人类。
问:发送和接收为什么是MessageBundle,而不是单个Message?
答:这是为了保证执行效率。在LiveChatV2中,用户每次的鼠标点击将会发送一个消息,如果用户鼠标点击速度相当快--比如每秒几十次,这么密集的访问可能会造成服务器没必要的繁忙。因此,客户端采取没隔一段时间记录一次,将这段时间的鼠标动作捆绑成一个消息包,发送给服务器。
其他问题,欢迎交流:mechiland [###] gmail.com
9 总结
AMOWA引入一种新的WEB开发模式,可以换掉标准的MVC开发方式了!
AMOWA的引入,从根本上讲,完全是为了给用户更好的体验,从而使产品更具人性化,更有竞争力。
更快。
2004年11月9日
http://www.pyrasun.com/mike/mt/
Mike Spille's Blog, 愤世疾俗,言词锋利,言之有物,让我一下子想起两个人,一个是javaeye的readonly, 一个就是raimudo. :)
2004年11月4日
进行比较简单的学习时,专家或者教师往往给初学者这样一种建议:以学习Java为例,初学者最好学习C语言,掌握基本的语言概念;然后编写Java版的helloworld,然后学习基本的java.lang, java.util库,在学习的过程中不断体会OO的概念;然后根据需要,学习某一方面的如网络,UI, WEB等等……
很明显,这是一个箭头状的直线学习图。但是实际上没有人纯粹的依赖这些建议或指导来学习成功,最终往往是两种结果:一种是学习过程枯燥无味,最终放弃或者依靠毅力苦苦挣扎;一种是在学习过程中不断参照已有知识,反复印证参考,最终其乐融融小有所成。
大部分人都处于第二种状态,或者自己没有意识这一点,在积累越多的工作者身上体现越明显。大脑是一个圆,需要学习来刺激使他膨胀,线状的学习思路会违背几何规律,最终让自己疲惫不堪,充满挫折感。
所以,学习,不断的学习,不限于技术方面的学习。这一点在Java领域表现得尤为明显。Spring的核心作者Rod Johnson在音乐上的造诣与技术不相上下,大多数国内J2EE技术比较强的人都有哲学背景。所以,一定要不断的学习,不仅要对技术世界,开源领域自己业务范畴内的技术永远保持敏感,而且要不断花时间充实自己其他方面的积累。总有一天,比如你在文学上的一个灵感会让你的设计充满惊叹;或者你在打桌球领悟到业务架构可以更加优化一些。
学习与年龄无关,与惰性有关,所以,保持学习的劲头,活到老,学到老。网状的学习过程,不限于本行业的学习视野,不断的体会领悟的积累,会让学习真正成为快乐。
2004年10月29日
Driver: com.ibm.db2.jcc.DB2Driver
用Squirrel SQL查看db2的数据结构,填好driver, url, username, password后,点“connect”,出现问题:
com.ibm.db2.jcc.b.DisconnectException: encoding not supported!!
奇怪,怎么会出现这个错误?我以为是SquirrelSQL的问题,运行了一下自己以前写的一个代码生成器,输入相同的参数,发现还是出现这个问题……头痛,以为是通过Console输入的参数编码与通过Java文件输入的编码不一致,索性打开Eclipse, Class.forName,然后getConnection,问题同样。
同事把代码拿去,在WSAD下面重新编译运行,奇怪,没问题;我也在WSAD下面重新编译运行了一次,居然也没有问题。
问题很明显了,是那该死的IBM JDK. 把Squirrel SQL运行的Java_home设置为WSAD的jre_home,问题果然解决,db2数据库结构正常显示在面前。
虽然问题解决,我还是不知道为什么——我也不想知道。记得以前jdom在webshpere上不能正常运行就把我弄得死去活来,这次又耗掉了我1个小时。IBM的jvm真是诡异。
2004年10月27日
在封闭开发。
想法少了,山清水秀的环境,不太繁重的工作(每天工作9.5小时左右),吃穿住都算方便的居住地点,隔半个月还能回城一次,每天还有时间打保龄、健身或者游泳,还有一群认识和不认识年龄相当趣味相投而性格各异的伙伴,我想说这应该是我参加的最舒服的一次封闭开发。
由于有其他的活动分散注意力,思维的速度明显慢下来,大脑得到了休息,以前的一些症状,如眼睛痛,左脑神经痛,见不得风,身体衰弱,后背起疙瘩,睡着了大脑都在思考等各种症状,明显的到了缓解。
上周到昨天在举行篮球赛,我们平台组不负众望夺得冠军。我也是很久没有打篮球了,好歹几天的加强训练,还能勉强打满半场。昨晚上庆功,以各种名目来劝酒的来了一拨又一拨,最后大家尽兴了,摇摇晃晃到了办公室,晕晕乎乎的打了一会儿CS,实在支撑不住回宿舍睡觉了。