另外这些框架即使是Webwork提供的是一种侵入式的方式. 所谓侵入式,就是说运行时环境的一些要素要侵入到我的类设计中. 例如使用Struts的时候,我们需要继承Action类,这个Action类就要侵入到我们的类设计中. 很多朋友也许认为使用一个框架就需要是侵入式的,如果不侵入如何能够完成一个类的设计呢? 这个观点是不正确的.Spring就是一个无侵入的框架(虽然在其web部分是要侵入的),如果只使用Spring的Ioc能力,完全只需要一个配置文件而已,实际的类不需要一行spring的代码. 进一步来说,实际上这种剥离侵入的也就是剥离一种耦合关系.例如剥离与Web环境的耦合。 我们实际上经常在做这些工作,比如服务定位器,就是要同服务进行剥离。例如一个服务是EJB服务,我们可以通过服务定位器剥离这个服务,让下层只针对EJB进行操作。 那么为什么我们不能剥离Web环境呢? 是不能吗?是不必要吗? 答案是可以,也有必要。当然不能是100%的必要,但是只要有1%的可能就值得去做。 仔细想想,剥离EJB服务也同样不是100%必要的。那么剥离的好处在什么地方? 健壮性、高扩展性,这就是目标。要实现健壮就需要程序能够充分的测试,单元测试是一个理想的技术,那么就要求形成可测试的单元。很多问题不能等到集成测试的时候来发现。 什么是可测试的单元? 单元的运行环境能够进行模拟的就是一个可测试的单元。 例如一个计算总价的函数,其输入是商品数量和商品类型,输出是商品总价。这个函数的运行环境是可以模拟的,通过编写测试用例,提供测试数据,可以模拟的运行。 回到我讲的Web,web环境是难以模拟的,如果我们的类中侵入了大量的Web环境,这显然是不合适的。 我大胆假设一下,而我们的java代码是非入侵式的与web容器无关的,我们的代码甚至可以在微软的服务器上运行,我们为Web编写的代码也可以在C/S结构上跑得很好,如果这个结构设计得足够好,你甚至不需要编写代码,需要的仅仅是配置一些运行环境。也许有人认为这是天方夜谈,那么XML是一种什么东西呢?XML的存在不依赖于任何东西,因此它可以运行在几乎所有的环境.我的类设计可以达到这个目的.当你谈到Dao模式的时候,你实际上是在做类与数据存储的分离. 当谈到Web层MVC的时候,你想到了什么? 难道你的Model需要和Web环境耦合吗?(如果耦合了才是糟糕的设计) Controller和View和Web的耦合看上去是天经地义的,但是真的如此吗? 如果我的视图是XML呢?这个耦合就不存在. 让我来分析一下使用XML和JSP的不同. XML的产生是由另一个程序控制的,XML按照何种方式显示也是另一个程序控制的. JSP的产生是程序员编写的,JSP的解释依赖于JSP的编写. 这就使差异,XML的方式XML始终是被动方,JSP的方式主动方始终是JSP(其实应该不考虑MVC环境下,这时候实际也是被动的,但是如果在JSP中处理了逻辑就不同了). 另外一些视图模版技术也达到了这个效果. 有的朋友应该看出来了,这就使依赖注入.编写一个组件的时候,组件不维护依赖,而依赖由更高层的东西注入. 也许有朋友要问,这个更高层的东西不是需要编写吗? 当然,但是这个高层的东西完全可以是一个框架. 视图的产生我们可以依赖于模版引擎,这就使框架.MVC的目的也就是将视图对数据的依赖,由Controller注入.好了MVC中只剩下Controller了,任何讲MVC模式都告诉大家,Controller直接面对用户请求,这无疑宣判了Controller必须要被Web环境侵入.但是这个侵入是必须的吗? Struts和Spring MVC都默许了这种侵入.除了Web,你难道能够将Struts的Action类用在其它地方吗? 这就是我谈到的Struts和Spring都无法脱离Web容器的问题. 幸运的是Webwork就在这里做到了.使用Webwork所产生的Action类,除了Web,仍然可以用在其它地方,只要你愿意. 但是我们仍然是在操作Web,我提到过有的东西可能只有在Web上做,而不能在其它地方做,这方面Webwork显得弹性不够(我也没深入的弄,因此不敢断言).也许很多朋友仍然认为,这种耦合是没有多大副作用的,相反效率更高,更灵活. 我不反对这种观点. 但是我希望他们至少理解,这种解耦是有价值的,哪怕只有1%的用处,况且实际的情况是用处不只1%,要远远超过. 实际上Struts或者Spring MVC推荐隔离这种耦合. When an Action class becomes lengthy and procedural, it may be a good time to refactor your application architecture and move some of this logic to another conceptual layer; otherwise, you may be left with an inflexible application which can only be accessed in a web-application environment. 这是Struts的帮助中摘录的,如果你仔细看帮助就明白其中多次出现类似的含义(只差明确说出来了)我敢保证很多朋友实际上也是按照上面所说的这么做的.既然Struts可以做到这点(以一种变通的方式),为什么还说是它的问题?这更应该是程序员设计时候的自觉选择. 那么MVC不也应该是程序员设计时候的自觉选择吗?为什么出现了Struts这种框架? 广泛需要做的事情,实际上就有做成通用模块的价值,这就使函数之所以产生,类之所以存在,框架得以发明的原因. 当然这个问题实在是太小了,不值得开放一个东西来支持,那我们在设计的时候是不是该注意? 我给Struts的Action类的使用原则是:从业务的上下文环境中提取数据,调用助手类完成业务,根据助手类的返回值确定下一步动作,如调用另一个助手类,将数据写回上下文,或者执行跳转.助手类必须脱离Web环境.如果发现很多Action类的步骤实际是一样的,就是该抽取公共方法的时候了.也许需要Template模式,也许需要继承,也许需要工具类.这些过程必然需要人来编写,如果我觉得这些编写太费时间,我会换一个框架,或者自己写一个简单的.
大概明白楼主的意思。我们不是运用structs的 而是自己公司的框架,不过相当接近了Action类(我们称为Command)代码大致是public class TestCommand extends BaseCommand { public String perform(ClientContext client) throws Exception{} }ClientContext 是一个Wrapper类,返回值是一个称为画面ID的值,这个值预先在配置文件中定义。可能经过一些改造,这个Action是完全可以被分离出来的。 例如提供ClientContext 这样一个的Wrapper类封装HttpRequest,HttpResponse 在单元测试中new出这样一个类,提供一个假的Wrapper类执行excute或perform应该是可行的。当然也可以对框架进行改造以满足你的需求。我想并不是很复杂。个人认为structs最烦人的地方是tag,它应该提供一个标准,实现可以自己来 而且tag很容易拖慢速度
我说的是struts和spring无法独立于容器而存在,也就是调试struts程序的时候需要一个web服务器,而且是必须的。
你要知道启动一个web服务器是一件非常痛苦的事情。
在weblogic下每次修改类文件都要重启服务器,确实是很痛苦的事情。现在我们开发都改在tomcat或jboss下了,这样对类进行修改后基本就不用重启服务器,除非是新增了form或action,对struts-config进行了修改才需要重启了。
Action是web层和领域逻辑的分界线,清晰的分层对单元测试很有帮助...
关于IOC,并不一定要使用Spring啊,尽量用代码解决问题,我认为
spring最大的好除就是透明的对事务进行控制,以及和hb的配合使用.
struts,大家说得比较多的缺点,一个是表示层和JSP捆得比较紧,可能还有Taglib和Control层设计得比较复杂,会增加学习的曲线.
不过,一俊遮百丑,它无疑是当今应用最为广泛的MVC WEB-FRAMEWORK了,所以可以得到最广泛的技术支持,没有什么比你在应用过程中遇到一个怪问题,而几天在网上也找不到同类的答案更沮丧的了.很多IDE也支持他.
当然,用不用STRUTS,怎么来用,要根据项目的规模自已定夺.如果项目组中每一个人都没有接触过struts时,选另一种方案也未尝不可(这种情况很小,很少有使用java开发web程序半年还不知道struts的人吧),我就觉得spring中自带的那个mvc就不错.
我倒是严重推荐spring框架,它的设计思想很值得学习,是面向组件的轻量级的.
第一,struts框架就是为解决web应用中的MVC框架的问题产生的。你说struts无法脱离容器,就好像说公共汽车不能在水中行驶一样。公共汽车不能再水中行驶,是因为它不是为在水中行驶而产生的,它的适用范围是在陆地上。你想用脱离容器的MVC框架,可以去找不依赖于容器的框架。
第二,关于struts对Ioc支持。楼主也说了,Ioc是新生事物,struts对Ioc支持不好,也不能简单归为它的缺点。
最后,个人觉得,脱离适用范围去讨论优点,缺点,是没有意义的。牛顿的经典力学公式尚且有其适用范围,何况struts。
楼主的意思是说,如何不用WEB容器或应用服务器就可以运行WEB页及WEB系统。 顺便楼主发个MAIL给APACHE开源项目组,问问他们struts是干嘛用的。梳子是用来梳头的,你非用它当牙刷用。
既然是web framwork 当然要靠 web container,
离开了web container,
还是web 程序了么?就算开发asp,
还需要,IIS呢.大家谈谈现在主流MVC框架在解决现有问题上的缺点是什么
楼主的命题无疑不错,
可是在自述时,
把问题放在,
"struts和spring的最大问题是无法脱离容器存在,这是一个严重的问题。"上,
小弟就不甚明了了.
例如struts中的action类无法脱离容器。
有朋友认为脱离容器是没有意义的,但是意义是很明显的。
我不仅发email给了apache的项目组,而且就这个问题和他们进行了讨论。
struts小组推荐在action中进行进一步的封装,按照他们的意思action类实际上并不适合来作为实际的控制类,这些实际的控制应该交给助手类。
例如可以采用如下的方式
public class TestAction
{
public ActionForward excute(HttpRequest request,HttpResponse response,ActionMapping mapping,ActionForm form)
{
Helper helper=HelperFactory.createXXHelper();
Result result=helper.do(request.getParameter("XXXX"));//可能有很多设计
//以下省略
}
}
如果按照这种方式,那么Helper类就是脱离了容器的,Helper类具有高度的可重用性,并且可以进行单元测试。我们完成的Web业务实际上是从Web环境中提取相应的数据,进行计算,产生结果然后写回到web环境或者其他环境。
因此这个实际的控制没有必要依赖于Web容器,而只需要依赖于Web环境中产生的数据。
特别是考虑到J2EE应用的客户端并不一定都是B/S结构的,这种方式就有更大的价值。
进一步来说,一个大型的J2EE项目,如果无法实现这种分离,那么就不可能做单元测试,只有集成测试。不能做单元测试这是不行的。让一个项目组中的所有成员都知道自己在操作Web,都给他们安装上一个Web服务器是不可能的。
如果我们的实际运行环境是一台小型机,难道要每个人都安一台小型机?
况且每个程序员手中应该只有代码片断,而没有整体,也只能单元测试。Struts可以通过助手类的来将控制类和容器分离,但是这就显得十分多余了。因为如果是Webwork,完全可以平滑的做到这一点。
strutstest是一个基于sturts的单元测试包,可以做单元测试,但是一个感觉就是用这个东西太慢了。如果只测试helperclass,那么测试的速度是这个的数倍。“既然是web framwork 当然要靠 web container"
不错,但是我写的东西不是Web framework,并且也不是绑死在web上的,那么为什么非要我的东西也混进web代码?那么我想知道为什么要用xml来做视图的?因为这样才不会被绑在web上面。
(当然纯的隔离对一些只针对Web的操作并不有效,这部分操作通常换成其他模式就没有编写的必要,在一个web环境中少之又少。遇到了编写也是一两个的问题)
所谓侵入式,就是说运行时环境的一些要素要侵入到我的类设计中.
例如使用Struts的时候,我们需要继承Action类,这个Action类就要侵入到我们的类设计中.
很多朋友也许认为使用一个框架就需要是侵入式的,如果不侵入如何能够完成一个类的设计呢?
这个观点是不正确的.Spring就是一个无侵入的框架(虽然在其web部分是要侵入的),如果只使用Spring的Ioc能力,完全只需要一个配置文件而已,实际的类不需要一行spring的代码.
进一步来说,实际上这种剥离侵入的也就是剥离一种耦合关系.例如剥离与Web环境的耦合。
我们实际上经常在做这些工作,比如服务定位器,就是要同服务进行剥离。例如一个服务是EJB服务,我们可以通过服务定位器剥离这个服务,让下层只针对EJB进行操作。
那么为什么我们不能剥离Web环境呢?
是不能吗?是不必要吗?
答案是可以,也有必要。当然不能是100%的必要,但是只要有1%的可能就值得去做。
仔细想想,剥离EJB服务也同样不是100%必要的。那么剥离的好处在什么地方?
健壮性、高扩展性,这就是目标。要实现健壮就需要程序能够充分的测试,单元测试是一个理想的技术,那么就要求形成可测试的单元。很多问题不能等到集成测试的时候来发现。
什么是可测试的单元?
单元的运行环境能够进行模拟的就是一个可测试的单元。
例如一个计算总价的函数,其输入是商品数量和商品类型,输出是商品总价。这个函数的运行环境是可以模拟的,通过编写测试用例,提供测试数据,可以模拟的运行。
回到我讲的Web,web环境是难以模拟的,如果我们的类中侵入了大量的Web环境,这显然是不合适的。
我大胆假设一下,而我们的java代码是非入侵式的与web容器无关的,我们的代码甚至可以在微软的服务器上运行,我们为Web编写的代码也可以在C/S结构上跑得很好,如果这个结构设计得足够好,你甚至不需要编写代码,需要的仅仅是配置一些运行环境。也许有人认为这是天方夜谈,那么XML是一种什么东西呢?XML的存在不依赖于任何东西,因此它可以运行在几乎所有的环境.我的类设计可以达到这个目的.当你谈到Dao模式的时候,你实际上是在做类与数据存储的分离.
当谈到Web层MVC的时候,你想到了什么?
难道你的Model需要和Web环境耦合吗?(如果耦合了才是糟糕的设计)
Controller和View和Web的耦合看上去是天经地义的,但是真的如此吗?
如果我的视图是XML呢?这个耦合就不存在.
让我来分析一下使用XML和JSP的不同.
XML的产生是由另一个程序控制的,XML按照何种方式显示也是另一个程序控制的.
JSP的产生是程序员编写的,JSP的解释依赖于JSP的编写.
这就使差异,XML的方式XML始终是被动方,JSP的方式主动方始终是JSP(其实应该不考虑MVC环境下,这时候实际也是被动的,但是如果在JSP中处理了逻辑就不同了).
另外一些视图模版技术也达到了这个效果.
有的朋友应该看出来了,这就使依赖注入.编写一个组件的时候,组件不维护依赖,而依赖由更高层的东西注入.
也许有朋友要问,这个更高层的东西不是需要编写吗?
当然,但是这个高层的东西完全可以是一个框架.
视图的产生我们可以依赖于模版引擎,这就使框架.MVC的目的也就是将视图对数据的依赖,由Controller注入.好了MVC中只剩下Controller了,任何讲MVC模式都告诉大家,Controller直接面对用户请求,这无疑宣判了Controller必须要被Web环境侵入.但是这个侵入是必须的吗?
Struts和Spring MVC都默许了这种侵入.除了Web,你难道能够将Struts的Action类用在其它地方吗?
这就是我谈到的Struts和Spring都无法脱离Web容器的问题.
幸运的是Webwork就在这里做到了.使用Webwork所产生的Action类,除了Web,仍然可以用在其它地方,只要你愿意.
但是我们仍然是在操作Web,我提到过有的东西可能只有在Web上做,而不能在其它地方做,这方面Webwork显得弹性不够(我也没深入的弄,因此不敢断言).也许很多朋友仍然认为,这种耦合是没有多大副作用的,相反效率更高,更灵活.
我不反对这种观点.
但是我希望他们至少理解,这种解耦是有价值的,哪怕只有1%的用处,况且实际的情况是用处不只1%,要远远超过.
实际上Struts或者Spring MVC推荐隔离这种耦合.
When an Action class becomes lengthy and procedural, it may be a good time to refactor your application architecture and move some of this logic to another conceptual layer; otherwise, you may be left with an inflexible application which can only be accessed in a web-application environment.
这是Struts的帮助中摘录的,如果你仔细看帮助就明白其中多次出现类似的含义(只差明确说出来了)我敢保证很多朋友实际上也是按照上面所说的这么做的.既然Struts可以做到这点(以一种变通的方式),为什么还说是它的问题?这更应该是程序员设计时候的自觉选择.
那么MVC不也应该是程序员设计时候的自觉选择吗?为什么出现了Struts这种框架?
广泛需要做的事情,实际上就有做成通用模块的价值,这就使函数之所以产生,类之所以存在,框架得以发明的原因.
当然这个问题实在是太小了,不值得开放一个东西来支持,那我们在设计的时候是不是该注意?
我给Struts的Action类的使用原则是:从业务的上下文环境中提取数据,调用助手类完成业务,根据助手类的返回值确定下一步动作,如调用另一个助手类,将数据写回上下文,或者执行跳转.助手类必须脱离Web环境.如果发现很多Action类的步骤实际是一样的,就是该抽取公共方法的时候了.也许需要Template模式,也许需要继承,也许需要工具类.这些过程必然需要人来编写,如果我觉得这些编写太费时间,我会换一个框架,或者自己写一个简单的.
而是自己公司的框架,不过相当接近了Action类(我们称为Command)代码大致是public class TestCommand extends BaseCommand
{
public String perform(ClientContext client) throws Exception{}
}ClientContext 是一个Wrapper类,返回值是一个称为画面ID的值,这个值预先在配置文件中定义。可能经过一些改造,这个Action是完全可以被分离出来的。
例如提供ClientContext 这样一个的Wrapper类封装HttpRequest,HttpResponse
在单元测试中new出这样一个类,提供一个假的Wrapper类执行excute或perform应该是可行的。当然也可以对框架进行改造以满足你的需求。我想并不是很复杂。个人认为structs最烦人的地方是tag,它应该提供一个标准,实现可以自己来
而且tag很容易拖慢速度
我也是这么做过的,不过是wrap了request,response、mapping和form。我想听听你说的tag方面的问题。
tag一多页面速度马上拖慢而且对于用户来说,我不需要用到那么多attributes(虽然require=false可以解决问题,但是这肯定增加学习曲线)
而且用户有不同的扩展的话,这样也很为难。
例如在textarea内输入回车,数据库update成\n
但如果在html代码内<c:out>的话,\n不会转为<br>
c tag也没有这个选择。也不一定是struts的问题,但提供那么多tag也不能完全满足要求,他应该是提供一个定义,这样用户可以自己扩展自己需要的部分。我也没有在项目中用过struts,只是自己稍微玩玩
其实这样一个框架也未必很难写,你如果对apache那几个common包都了解了,可以省掉很多麻烦。
我个人认为存在Web应用是因为现代信息造成的。
web应用就耍web程序,这是由于web程序比以往程序具有易开发,
多用户可使用,客户端简单造成的。
可是为什么用java开发web程序如此之难,是由于目前还没有一个好的
IDE,能把所有的JAVA技术合成一起。就像.Net一样。开发.Net程序是很简单。
我想,不久,就会有这种IDE出来。
IDE,能把所有的JAVA技术合成一起。就像.Net一样。开发.Net程序是很简单。
我想,不久,就会有这种IDE出来。
========================================================================================
我觉得实事恰好相反,java没有好的IDE并不是它的劣势,或者说有没有IDE和技术是没有关系的。软件开发的问题,归根结底是算法的问题。而应用型软件的,这个算法是不好搞定的。一是由于我们设计算法的时候需要明确的问题描述,但是应用型的软件准确的应用描述难以获得,其次面临的问题很难以数学方式来表达,这使得现有的科学技术根本就用不上。这两方面直接导致了,应用型软件的算法采用了最低效的方式来设计,也就是Brute force方法,直接靠蛮力来解决。这种方式对问题的抽象层次是不够的,抽象层次的不够导致了大量复杂的重复的操作,直接反映到程序中就形成了严重的问题。个人认为软件工程中的众多管理,原因就是应用软件开发中采用了一个非常低效率的算法,因此不得不靠管理来控制这个算法的执行。(这个算法甚至要求人的直接参与)无论你采用何种IDE,问题的核心仍然是:描述问题、解决问题(设计就是如何采用更优的方式来解决问题),这些问题实际就是算法问题。标准的IDE可以快速开发,这也不过是建立在有良好的设计的基础上,糟糕的设计并不会因为IDE的改变而加快。JAVA社区现在面临的问题多半是企业应用,这些应用的关键问题就是设计,而非什么IDE。
做一个桌面应用所面临的问题和企业应用面临的问题,在问题的复杂度上就不是一个档次的。
举个例子,设计一个IE浏览器所要考虑的问题远比设计一个大型企业的ERP系统要少得多。虽然很多人认为设计IE浏览器在技术上更为困难,但是面临的问题就这么几个,只要能够解决,那么剩下的部分不过是编程实现而已。而一个ERP系统问题的数量都可能是不固定的,虽然每个都显得简单,但是问题可能多得让你可能无法在有限的时间内解决完。
=====================================================================================
我同意这种看法,用ms的开发工具就需要等待微软的施舍。虽然微软的IDE确实很好,但是我们要解决的问题是如此复杂,ms不可能都给我们解决,而它的IDE自身扩展性太差了。当然扩展性和高集成本来就是有所矛盾的。
看看这里这么多faq的问题就知道了。
(所以如果更多的东西被列入faq里去,检索更容易一些,我相信java版日复一日的问题不会那么多)跨过这么门槛后
就是面对林林总总的framework之类的犯晕。的确是太多了,以至于无数人把jarkata的也盖到sun头上去了。这个也没什么说的,用过一次就明白了。当然,现在讨论的最多的还是设计,过度设计等等。包括分层等等基本概念。但是为什么每个人都知道要分层,要MVC,要运用模式。为什么还是有那么多做的不死不活好死赖活半死半活的项目?为什么还是抱怨java难开发?难在哪里?
配置?我认为这对有经验开发者不是问题
部署?是一个问题,但是单纯servlet可以reload,ejb的也有热部署。良好的单元测试可以避免无意义的重复部署。
单步?那也不是问题,remote debug一样可以单步调试。和vs里面一样。归根到底,我认为太多的人只关注代码,缺少了对用户需求的准确分析。可以说,需求分析决定了软件开发的成败。而设计,只要设计的不是太烂太耦合,都是可以一步步的重构的。但是如果需求改了,设计的框架不符合需求,那就只有彻底的返工。为了不只做一个coder,必须要关注,要参与上游设计。要指出设计中的不足之处,要为将来的扩展留下余地。更重要的,是要理解业务,要提前想到客户没有想到的那些东西。难吧,是很难。
我们不一样,一个项目里面居然用了四个框架,连struts都被进一步封装了。下面还用了几个日本人产的玩意,特烦