action层的作用感觉越来越小

现在有些项目采用struts2,jsf之类的,所以页面上的值自动绑定到action了,也不用像以前再从request里面取了,很多action的作用就是把自动绑定的值传给service层(顶多是做个类型转换),然后通过service返回的参数进行跳转。既然这样的话可不可以直接把service和action合并成一层呢?如果这样做不好,那理由主要是啥呢?action层除了获得view数据,跳转,还应该承担什莫作用呢?谢谢!

本来就承担这些作用。那些在Action里写代码的都是错误设计。Action本质上来说是MVC中控制器的一部分。本身就只承担调用业务对象、根据结果转发到响应视图的功能。在Action里写业务代码,是因为在学习框架的时候,照书抄的。书是为了介绍框架的,所以在这方面就不太注意。使得很多人养成了在Action里写业务代码的坏习惯。
说到这里,写Hibernate框架书的也有这个问题。书上介绍的是框架,但是有时候对如何在项目里正确使用框架没有写。造成很多人在Dao里写业务代码。
最后两边把Service层的功能一分,三层架构变二层了。Service里除了一句Dao的调用代码,什么也没有了,典型伪三层结构。

关于你说的伪三层结构肯定是错误的,既然分了三层,那就应该各司其职;我所疑惑的是,在目前高速发展的框架下,为啥还要用三层结构。现在action本身并没有显式的取页面数据了,而是由框架采用IOC方式set进来的,而跳转也是依赖于service层所返回的参数进行的(有些项目service层函数返回的参数就是"success"之类的),这样的话action层存在的目的何在呢?或者我没有考虑到在其他一些情况下action还是有作为的?

>service和action合并成一层呢?如果这样做不好,那理由主要是啥呢?action层除了获得view数据,跳转,还应该承担什莫作用呢

你的思路非常好,Action的作用是很小,但是不能和Service/Action合并在一起,因为Action属于表现层 而Service属于业务层,多层架构不能破坏,否则又回到两层的Delphi时代。

那有没有又不需要Action,但能保留Action的方式呢?有,Jdon框架2004年就做到了,也就是不需要写Action代码,但是可以配置Action,这样达到两全其美。

当然,相信这些老外技术除了走上述国人Jdon框架这条路,还有其他更好的路可以解决上面两难问题,拭目以待。

嗯,非常感谢。其实不是说action层不重要,而是现在的很多框架已经帮我们做了很多action层要做的东西,所以我们自己的应用里面action所作的东西就少了。
关于两全其美的办法,我现在是采用只写一个action,然后动态调度该执行那个具体的service。因为绝大多数页面的action都一样,如果以后有需要在添加新的action类型;总的来说就是把action分类,而不需要为每个页面都写一个action,banq大哥你觉得靠谱吗?

看了一下seam框架,框架管理着action,IOC灵活得不可再灵活了,不管是dao还是service,想怎么注射就怎么注射,框架的案例中hiberante的session以及EJB3的EntityManager都注射到了action中,用了Jdon,seam的这种编程方式我咋个就不习惯呢?
Jdon框架强制你对系统进行分层,aciton空壳,编接口和实现,然后配置组件让容器autowiring,要服务自己到容器里面去取。建议初学者把Jdon学一下先,如果直接用seam这些注解类框架,谁教你分层啊?

>总的来说就是把action分类,而不需要为每个页面都写一个action,banq大哥你觉得靠谱吗
对的啊,jdon框架也是这个思路实现的,真理总是站在善于思考人这边,软件永远只是思想的结果。

关于seam框架,在它一出世我就说了,乖乖,把Ioc发挥到极致,到底是外国人,剑走偏锋,出奇制胜。其实Seam这种Ioc方式,就是国内某个大公司框架自我吹嘘的IoVC。

Seam这样做,好处当然有,但是缺点很显而易见,多层之间本应相互解耦,结果现在可能适得其反,你可能在Action中耦合持久层或其他非业务接口的代码。因为你总是要在代码中提供注射通道,打个比喻,两块木块要连在一起,不管是谁先主动发出连接对方(这些都是连接方式IOC/DI解决的就是连接方式),总是要在一个木块中开个凹槽,另外一个开个凸槽,这样凸插入凹就是注射通道。

为什么Action不能耦合太多代码?
首先从修改维护性上考虑,Action本来就是一个前后台调度的调度者,将前台用户输入传递到后台业务处理,将业务处理结果再传递到前台界面,Action就是一个二传手,说文一点,是Mediator模式实现,二传手就是二传手,不能充当前锋,也不能充当主力,这就是分工。

再打个比喻,警察在十字路口指挥交通,这个警察就是Action,这个警察职责就是调度指挥职责,不能将其他更多职责给他了,否则就违反OO设计原则。

所以,从这个意义上讲,我们将Action低调化处理,不完全消灭它,让它只出现在配置中就可以了,在这个配置中,它完全发挥了调度指挥事件流的作用。

confuse,你说:“我现在是采用只写一个action,然后动态调度该执行那个具体的service。”
请问能给出一些具体配置和代码吗?

>我现在是采用只写一个action,然后动态调度该执行那个具体的service
可以看看Jdon框架中的ModelSaveAction类。

我在各个界面调用action的时候加入两个参数
一个是service的名字e.g.: login自动加上Service--〉loginService
第二个是这个service的方法名,参数没有的话有默认处理;
靠这两个参数定位到service里面的一个具体方法。
页面上的值都存储到一个dyncDTO类里面,这个是个HashMap,共通的action直接把它传递给service。

例如:
<action name="login" class="commAction" method="doOperation">
<param name="service">login</param>
<param name="operation">login</param>
<result>/WEB-INF/pages/list.jsp</result>
</action>

banq先生,您不能因为seam可以将业务写在action中,就认为seam必须这样做。
我明明可以写一个OperateService来完成业务作业,而在action中@In OperateService的。
简化是个诱饵,但是seam的好处不仅仅在于这惟一的简化,还有其它的好处,比如权限处理更加简单,Observe更加简单,只需要用注释来注册它即可。