基于《关于Java开发不明白的一些问题》,探讨一下Struts1和Struts2

 

链接:http://www.javaeye.com/topic/952027

在《关于Java开发不明白的一些问题》中提及Struts1和Struts2,

只不过是用来作为讨论解耦的一个例子而已,我没有从整体上评价孰优孰劣

事实上,我也是先接触了Struts2后来才看的Struts1,

看到一些把Struts2拿来膜拜,我觉得自己是不是应该好好反思一下?


凡是做过JavaWeb开发的莫不了解MVC,凡是了解MVC的莫不了解Struts

纵观java世界里的Web框架,无论形式上如何变化,其本质上却是大抵相同的

所有,不要见人就问你懂不懂某某框架啊

懂框架不如懂原理,举一反三的道理人人都懂,却不是人人都能做的到

那么,那么多的框架,本质是什么呢?相同点又在哪里呢?

其实,无论外表搞得多炫,核心还是Servlet驱动的

而驱动的模型无外乎两种:请求响应驱动和事件响应驱动

我知道的,基于事件驱动的框架有Seam,

而基于请求响应驱动的就很多了,如Struts1和2,XWebWork,Spring-MVC等等

脱离了这些框架之后,所有的东西都能有Servlet实现

而Servlet+JSP+JavaBean就是一个无任何框架的开发模式

这里看好了,JavaBean框架无关的,而JSP现在有多有视图模型可以替代

那么,框架的主要功能是什么呢?,就是取代Servlet的逻辑控制作用

在Struts中,取代Servlet的对象就是Action,

下面,我们来看看Struts1和2中Action的角色有什么不同

在MVC框架中,M作为数据承载的对象,是有状态的,

具体讲,就是一个对象有属性,通过方法的调用来改变属性的值,从而达到状态变化

如果M纯粹作为数据载体的话,那么它的状态变化需要外界来驱动

就像一辆车子,车子本身是不能动的,需要由人来驾驶

在String1中,M就是ActionForm,而C就是Action,

通过Action调用方法并将ActionForm作为参数,来改变ActionForm的属性,

从而完成对客户端的响应

这里,Struts1的一个弊端就是这个JavaBean不是框架无关的,而是需要继承框架的一个基类

为了解决这个弊端,到了Struts2,Struts已经完全否定了自己,转投XWebWork的怀抱

我想说的是,这个自我否定,做得有点过火了,因为你从本质上将还是一个Web框架,

我们将耦合与内聚,你把粒度放大,其实耦合不过就是更大粒度的内聚

不是解耦不是为了方便,耦合的越紧效率越高,使用越方便,这就是集成,它的缺点就是不适应变化

那么我就说了,Struts2你再怎么变化就有一点是不需要变化的,

那就是——你究竟不过是个Web框架

我们来看看Struts2的Action,

第一,action本身包含业务逻辑的数据,那么它承担着M的角色

第二,action还能执行方法,改变自身的属性,那么它同时承担这C的角色

所以在Struts2中,action是自驱动的,不需要外界的干涉,便能改变自己的状态

这就像一辆无人驾驶的汽车一样,有些人觉得这很爽,有些人觉得很不爽?为什么呢?

——因为有些人喜欢开车,有些人不喜欢开车!

也就是有些人喜欢自己控制代码的流程,而有些人却想什么都交给框架做



基于以上的比较,我们来看看Struts1和Struts2有关解耦的问题

可以这么说,即使什么框架都不用,纯粹的Servlet+Jsp+Bean都能解耦,

所以没有什么框架不能解构的,如果你觉得不能解耦,那么就是你的代码设计本身有问题?


还是举个例子吧:

有人说,Struts1中action方法里带有Request和Response对象,无法解耦

我想说,至少有两种办法来解耦:

第一,自己创建Request和Response对象对象

这两个对象不过就是个接口声明,你完全可以有的实现,如果使用了适配器模式,那就更方便了

第二,在需要从Request对象获取数据的地方,将变量提升为参数或者属性同样可以解耦


还是一点想说的是,解耦不过是个概念性的东西,主要是为了应对变化,

但是,现在好多人把解耦简单地理解为,我不继承你的类或接口,就是解耦,

这真是匪夷所思!!!!

再举个例子吧,看看所谓的Struts2的解耦~

对于一个数据对象,它就是一个Bean,

这个Bean是框架无关的,它只包含了业务数据,我们可以将它用到各个框架中,

但是在Struts2中,它是一个action,同样包含了业务数据,但是同时包含了业务逻辑

因为它没有继承Struts2的任何接口和类,你认为它是解耦的,

但是当你把它用到其他框架中,有用的只是它的数据,而不是它的处理方法,因为它的处理方法只有Struts2的框架有用

这种解耦的代价就是代码污染,因为一个数据对象到处包含着不能共享的业务逻辑处理方法

把这种情况放在Struts1中,你可能会说它需要继承一个ActionForm类,

不错,的确如此,但是仅仅这一个类,就可以让你免除那么无谓的代码污染

因为这个类属于Struts,你就认为耦合了,如果在JDK中,你就不那么觉得了?

JDK中的类和我们自己编写的类有区别么?除了身份不同罢了~~~~~~~~~


到了这里,也许你会说,我可以对业务数据进行包装,进行从Action到JavaBean的转换,

那么你可以这样,同样Struts1中也可以进行ActionForm到JavaBean的转换,

所以本质上的解耦根本不是由Struts2来提供的,而是在于你的代码设计

发这个帖子的目的,就是想澄清一下Struts2所谓的解耦,不过玩的概念而已

当然你以可以喜欢它,毕竟比Struts1开发更方便

也可不喜欢它,因为它让你更远离技术


在人家玩概念的时候,也许我们更需要明白的是概念表面下所隐藏的实质,

也许这实质不是我说的这样,但是学习不就是一个不断思考的过程么?


PS:

框架自然有它的好处,不然不会有那么多人用它,但是它无形中造成了程序员价值的贬值

个人的愚论:越是底层的知识,有效期就越长;越是上层的东西,依赖性越强~~~~~~~~~~

从更宏观的角度来讲,整天跟着框架跑,奔波于了解和掌握框架的最新特性,

倒不如研究一下框架本身隐藏的技术手段,能够做到以不变应万变

一旦哪天框架的开发者宣布不再维护了,那么,

是否你的学习就到了尽头了呢?还是继续寻找新的替代者? 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值