论坛首页 Java企业应用论坛

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

浏览 9919 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (16) :: 隐藏帖 (4)
作者 正文
   发表时间:2011-03-10  
在《关于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:

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

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

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

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

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

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

   发表时间:2011-03-10  
从更宏观的角度来讲,整天跟着框架跑,奔波于了解和掌握框架的最新特性,
倒不如研究一下框架本身隐藏的技术手段,能够做到以不变应万变

非常赞同这个

0 请登录后投票
   发表时间:2011-03-11  
struts/struts2/spring mvc,团队用哪个,你就用哪个就是了
这种框架日经贴,还非要比出个123来.......
0 请登录后投票
   发表时间:2011-03-11  
严重同意楼主,框架是如此之多,生命是如此有限,会举一反三才是硬道理!
0 请登录后投票
   发表时间:2011-03-11  
第二,action还能执行方法,改变自身的属性,那么它同时承担这C的角色

所以在Struts2中,action是自驱动的,不需要外界的干涉,便能改变自己的状态
-----------------------
不理解,不也是请求响应么,没有外界请求怎么改变自己的状态了?


还是举个例子吧:

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

---------------------------
有了Request,Response为什么就会无法解耦了,他们不都是Servlet的对象么?
求解答
0 请登录后投票
   发表时间:2011-03-11  
引用

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

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

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

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

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


严重赞同...
0 请登录后投票
   发表时间:2011-03-11  
Jazag.van 写道
第二,action还能执行方法,改变自身的属性,那么它同时承担这C的角色

所以在Struts2中,action是自驱动的,不需要外界的干涉,便能改变自己的状态
-----------------------
不理解,不也是请求响应么,没有外界请求怎么改变自己的状态了?


还是举个例子吧:

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

---------------------------
有了Request,Response为什么就会无法解耦了,他们不都是Servlet的对象么?
求解答

自驱动和被驱动的区别就是,还是那汽车做例子,一个是无人遥控汽车,一个是人工驾驶的汽车
在Struts1中,JavaBean作为参数,从其他类调用方法改变状态
在Struts2中,Action本身作为JavaBean,它是自己调用自己的方法
我不明白你怎么不明白呢?
还有,我没有说自驱动和请求响应由什么关系
一个是面对类来说的,一个是面对框架来说的


这里所说的解耦的意思,Action类的定义不需要引用其他非常用的类
有Request和Response对象,你就必须引用Servlet API,这就和Servlet API耦合了
同时方法参数还有ActionForm和ActionForward,这就和框架本身耦合了
0 请登录后投票
   发表时间:2011-03-11  
你在 Struts2 中用 ModelDriven 时,它的解耦就不会是个概念问题了。
0 请登录后投票
   发表时间:2011-03-11   最后修改:2011-03-11
1.在struts1中M就是ActionForm?
模型还包括Service,Dao,还有我们的pojo
actionForm通常都可以用pojo来替代
2.struts是一个web框架,但是你有没有想过为什么struts2要和servlet api解耦合?
我想一个主要的原因就是为了便于测试
(1)你说自己构建Request和Response?
不要忘了,execute方法中传的参数是HttpServletRequest,不管怎么说还是会和servlet api耦合
而且你还需要构建一个ActionMapping
(2)在需要从Request对象获取数据的地方,将变量提升为参数或者属性同样可以解耦?
提升为参数指的是在execute上添加一个参数吗?
execute的参数是固定的,不能改变
提升为一个属性指的是在action上添加一个属性吗?
struts1的action是单例的,你这么做会导致线程不安全
而struts2完全避免了与servlet api的耦合,request,response都转换为了Map,这样你可以很方便的写测试
总之,建议你在写下两个框架的action的测试代码,
你要是能写出一段struts1比struts2方便的测试代码那我就没有什么好说了.
3.Struts2中,它是一个action,同样包含了业务数据,但是同时包含了业务逻辑?
刚才已经说了,业务逻辑是不应该出现在action中的,不管是struts1还是2
4.JDK中的类和我们自己编写的类有区别么?
当然有区别,如果你毫无顾忌的这个类引用那个类,当你想要重用这个类的时候你就会发现是多么麻烦的一件事了


0 请登录后投票
   发表时间:2011-03-11  
看完楼主的写的表面上振振有词,其实全部在扯淡。MVC理解不到位,解耦思想也不到位,对框架的认识也不到位。
“在String1中,M就是ActionForm,而C就是Action,

我就不知道你读过struts的源码没有,action是控制器?Action是模型?佩服啊!!!
“Servlet+JSP+JavaBean就是一个无任何框架的开发模式


又在说些火星的语言,是Servlet+JSP+JavaBean不是mvc模式么,楼主你在说笑吧?

“如果在JDK中,你就不那么觉得了?

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


又说些搞笑的的话,JDK有的,你还需要写么?

还有,楼主说自建一个request,response就可以解耦合,真不知道你的脑子里想的啥...
楼主就是一个新手,不想多说,跟你多说你肯定会反驳,


0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics