在使用WebWork进行开发的过程中,她的种种特性:简约为先的设计原则,IOC的实现,Interceptor的使用,Command模式的使用,利用OGNL作为其Expression Language,完备的类型转换,简便的配置以及完备的Validation都深深打动了我,让我将其列为开发Web Application的第一framework。然而,金无足赤,强大的背后却有着或多或少的pitfall。
首先,作为一个框架本身,它提供的文档还是不够充分的,sample也比较匮乏,而且文档中也存在与范例不一致的地方,使得学习WebWork的曲线没有想象中的那么平滑。还记得有篇文章在比较框架之间优劣的时候,文档因素是被列在第一位的。因此,增加足够充分的文档与sample,是WebWork社区的当务之急了。
其次,也许是与Velocity紧密结合的缘故,因此WebWork在表示层做得并不好。譬如她提供的Tag Library,除了与ValueStack相关的几个标签具有一定的实用价值之外,其它的tag都让人觉得鸡肋的感觉。其实将页面上的UI元素封装成tag是一个不错的选择,但是WebWork的UI Tag做得并不出色。举个例子,<webwork:textfield>标签封装了<input type="text">,然而我却没有办法象使用<input>那样使用<webwork:textfield>,最重要的就是没有办法将CSS样式应用到她上面,如果加上class的属性的时候,tag在parse的时候就会报错。正是因为这个,我不得不弃用所有的UI标签。我想在UI上面,还得向ASP.NET多学习了。
第三,虽然Validation框架提供了通过配置actionName-validation.xml的文件即可完成字段校验的大部分工作,但是如果某些字段的校验需要涉及数据库的查询,那么这样的方式不适用了。在类ActionSupport中定义了两个方法:addFiledError和addActionError,两者对应的参数的区别在于前者除了error message之外还需要一个参数就是field name,而后者就只有error message了。从这两个方法我们可以看出框架定义了两种层面上的错误,一种是Field级别的错误,一种是Acition级别的错误,那么我们应该将涉及数据库查询的字段级别的校验归为哪一类呢?其实,我个人认为这样的接口设计并不是最优的。首先action级别的错误也可能是由于字段不符合要求导致的,但是这样的校验需要数据库查询的支持,因此,我更加愿意让addActionError也带上field name的参数。其次,两种层面上的错误是可以统一起来的:
addValidateError(String fieldName, String errorMessage);
addValidateError(String errorMessage);
综合起来而言,我会选择将Validation写在每个action中,这样会让Validation更加集中,使用了配置文件就不可避免地将Validation分散在各处了。如果你担心代码的重复的问题,完全可以将类似的校验归并到一个Util类中,供所有的Action调用。