链接: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:
框架自然有它的好处,不然不会有那么多人用它,但是它无形中造成了程序员价值的贬值
个人的愚论:越是底层的知识,有效期就越长;越是上层的东西,依赖性越强~~~~~~~~~~
从更宏观的角度来讲,整天跟着框架跑,奔波于了解和掌握框架的最新特性,
倒不如研究一下框架本身隐藏的技术手段,能够做到以不变应万变
一旦哪天框架的开发者宣布不再维护了,那么,
是否你的学习就到了尽头了呢?还是继续寻找新的替代者?