代码改变世界

WebWork深入探索之初见端倪

2004-08-19 16:35  FantasySoft  阅读(...)  评论(...编辑  收藏

        使用WebWork进行Web Application开发也有一个星期了,虽然对于WebWork框架本身的设计思路感觉还是一片模糊,但是我开始看到了一丝的光线。
        虽然在前文提出的问题[1],现在并没有一个很好的答案,但是在WAF和WebWork的比较之中,我发现了越来越
多的差别。尽管这些差别并不是完全由两者设计的差异造成的,我想或多或少会有一定的联系。就让我们继续在比较中摸索前进吧。
        1、Action与HtmlAction之间最大的区别,就是Action更加的简单与纯粹。在Action中,我们根本看不到
HttpServletRequest的痕迹,execute方法并没有包含任何参数,因此Action就是纯粹的业务逻辑主体,不搀杂任何其他无关的内容。而在HtmlAction中,perform方法的参数就是HttpServletRequest。这样的话,HtmlAction确如其名了,只能用在Web应用中,一旦改变了表示层,根本就没有办法实现移植。相比之下,Action由于没有和某种特定的表现技术绑定在一起,仅是业务逻辑的主体,就可以很容易的进行移植了。
        事实上,在WebWork中,httpServletRequest只是出现在了类ServletDispatcher中,但是呢,
ServletDispatcher的工作只是将request包装了一下,并且建立一个extraContext,然后将extraContext作为一个重要参数传递给ActionProxyFactory类的createActionProxy方法,并且由这个方法返回了一个ActionProxy的实例,最后调用ActionProxy的execute方法,完成所有的操作。在这里,有三个地方需要做进一步的说明,一个是extraContext,一个是虚类ActionProxyFactory,而另一个则是createActionProxy方法。extraContext本身并没有什么特别的地方,它就是一个HashMap,在这个HashMap中,Context按照作用域的不同,分成parameterMap,sessionMap,ApplicationMap,requestMap等几个部分;ActionProxyFactory类承担着两个任务:创建ActionProxy和创建ActionInvocation,而createActionProxy方法担起了创建ActionProxy的任务——调用了实现ActionProxy接口的类(在这里是DefaultActionProxy)的构造函数;而创建ActionInvocation则是在构造函数中完成的,毕竟ActionInvocation的实例必须与一个ActionProxy实例相匹配。
        2、Action与HtmlAction相比,还有一个很重要的不同,就是通过Interceptor的使用,实现了一定程度的
AOP。在HtmlAction中,我们通常都需要调用getParameter方法,将页面中form所包含的元素一个个从request中取出来,事实上这些代码重复是不必要的。在WebWork中,Action的调用是由ActionInvocation去完成的,但是在Action被调用的过程使用了Interceptor(拦截器),由Inteceptor去完成在大多数Action被调用过程中都需要处理的逻辑。这好比在Action被调用这个纵向过程中增加了若干个横向切面,这就是AOP的一个基本思想。再回到刚才所说的从request中获得form所包含的元素的例子,在WebWork中,我们看不到getParameter的身影,说实在的,刚开始我还真的不习惯,还担心我需要的元素是不是真的取到了呢。我的担心根本就是多余的,在Action被调用之前,或者说是在ActionInvocation的invoke方法被调用之前(Action中的execute方法是在invoke方法中被调用),ParametersInterceptor就已经帮我们做好了这样烦琐的事情了。我们所需要做的就只剩下在Action中增加与页面中form所包含的元素对应的setter方法即可。
        3、Action与HtmlAction相比,从测试的方便程度来看,很明显Action更加易于测试。象以前在做
HtmlAction的测试的时候,我不得不模拟一个HttpServletRequest作为参数传递给perform方法,而在Action的测试当中,根本就不需要这样。我们从Action被调用的代码即可以看出其简洁:

ActionProxyFactory factory = ActionProxyFactory.getFactory();
ActionProxy proxy 
= factory.createActionProxy("""Login"null
);
System.
out.println(proxy.execute());    

        通过比较,我们可以发现这样的设计为我们的开发带来了莫大的好处,可是我又开始想了,如果不这样设计,或者说换了另外的设计,我们能够拥有如此好的可移植性、灵活性和可测性吗?

        [1] WebWork深度探索之盲人摸象