项目做的的久了,却发现自己很多时候不知道如何做了

项目做的的久了,却发现自己很多时候不知道怎么做了。
最近想把手头项目规整一下,发现很多东西在过去想做没做成,但是现在真想做的时候,不敢下手了。
比如
第一个问题,STRUTS2通配符配置问题:
<action name="*_*" class="com.{1}Action" method="{2}">...
我的疑问是,Action那么多类,全都放到一个包下边吗?像上边的例子里,基本上JSP都在一个路径下,CODE也在一个包下,如果项目大的话,恐怕会很恐怖啊。
过去我们是一个模块的ACTION放到一起,模块是一部分包路径,但是,现在整理代码的时候,如果使用通配符配置,那么就要把所有的ACTION放到一个包里,因为开发都是自学,没接触过其他公司的项目,无法知道其他项目是怎么做的,但是这样整理,我感觉很不舒服。

第二个问题,类与包的问题:

我们的项目中一个模块或者子模块要有独立的SERVICE,IMPL,DAO,加上ACTION,MODEL
过去两个项目做了不同的放置方式,
一种是com.part1.a.service.Aservice,com.part1.a.serviceImpl.AserviceImpl,com.part1.a.model.A;
另一种是,
com.part1.a.Aservice,com.part1.a.AserviceImpl,com.part1.a.Adao;
不知道有没有更好的放置方法?
其实这么放都是为了找代码的时候方便快速,但是前者创建了太多的包,基本上每个表都要有4-5个包保存,
后者所有东西放在一起,感觉好像层次感欠缺。

第三个问题是,接口使用的问题:
比如说,删改增作为一个泛型接口,del<T>等,是抽成一个通用的接口,让每个SERVICE继承好,还是每个SERVICE写一遍?比如我以前的一个同事常用的写法:delA(); updateA();
基于这个问题,其实还有一个相关的问题,就是实现类中,是每次都重新实现好,还是继承自一个父类实现类(其中调用一个基础的DAO进行通用的增删改操作),当特殊需要的时候重写父类方法?
过去我曾经做过继承的写法,但是后来出于可读性的考虑,又回归了原始写法,即基本的操作全都定义出来,包括DAO中也重新定义一遍。

第四个问题,继承问题:
假如第三个问题的解决方法是使用继承的话,是整个项目继承自一个基类,还是每个模块各自建立一个父类继承?如果都继承自同一个基类,以前曾经有过方法增加数量太大,无法减肥的时候(也许是我的水平不够),也好像每个模块不能单独运行。


第五个问题,工具类库的问题:
当时间很长的一个项目,写了很多工具类库,这些类库又依赖一些相关包,当一个新的项目不大需要这些工具类的时候,相关包的删除就成了问题,我想知道,是否应该在每个新项目建立的时候,都保留所有的工具类库?

第六个问题,JSP文件及JS存放问题:
基本上每个页面都有很多JS,有些抽成通用的,有些没有,我想知道的是,比如一个USER操作的相关页面和JS ,在项目里是怎么放置好?建什么样的文件夹保存JSP,什么样的文件夹保存JS,需要不需要都放在统一的模块下边,还是JSP与JS就是两大块全部分开?


其实也知道,这些只是规范问题,我真的想知道这些规范都是在什么情况下被人提出而被人认可的,这些规范的来源,被提出的原因,解决的是什么问题,思考一下,如此而已。




1 楼 ak121077313 2011-04-26  
1、一个模块一个package

2、我的写法是1个baseDao 1个baseService 一个package放bean,另外一个项目baseService也不要了。当然是小项目更方便。

3、我的写法是:<T> T get(Class<T> clazz, String where, Object... values);//查找单个

4、没注意

5、工具类 用在新项目中也可以的啊。去不去掉无所谓,还有apache的common包

6、静态文件放一个目录下,无法公用的在js文件夹下面建子文件夹user区分,jsp文件放在web-inf下面

2 楼 weiqiang.yang 2011-04-26  
第二个问题,类与包的问题:

我们的项目中一个模块或者子模块要有独立的SERVICE,IMPL,DAO,加上ACTION,MODEL
过去两个项目做了不同的放置方式,
一种是com.part1.a.service.Aservice,com.part1.a.serviceImpl.AserviceImpl,com.part1.a.model.A;
另一种是,
com.part1.a.Aservice,com.part1.a.AserviceImpl,com.part1.a.Adao;
不知道有没有更好的放置方法?
其实这么放都是为了找代码的时候方便快速,但是前者创建了太多的包,基本上每个表都要有4-5个包保存,
后者所有东西放在一起,感觉好像层次感欠缺。
--
我更倾向于第二种方式
com.part1.a.Aservice,
com.part1.a.AserviceImpl,
com.part1.a.Adao
1) 重构方便,不用到处找相关的代码,都在一个目录下,如果要删掉这个功能,那么删掉这个目录就可以了
2) dao可以设置成包可见,对外不可见,避免dao被外部直接调用
3) 至于你说缺乏层次感,我觉得不会,在命名规范(*Service, *Dao)上已经体现了层次,实在不行,可以在内部继续分service,dao目录
3 楼 tfwin2 2011-04-26  
ak121077313 写道
1、一个模块一个package

2、我的写法是1个baseDao 1个baseService 一个package放bean,另外一个项目baseService也不要了。当然是小项目更方便。

3、我的写法是:<T> T get(Class<T> clazz, String where, Object... values);//查找单个

4、没注意

5、工具类 用在新项目中也可以的啊。去不去掉无所谓,还有apache的common包

6、静态文件放一个目录下,无法公用的在js文件夹下面建子文件夹user区分,jsp文件放在web-inf下面


兄弟可能误会我的意思了,不是想知道你怎么弄,而是想知道为什么这么放,呵呵,不过还是感谢你的回答,至少让我有个比较。
4 楼 tfwin2 2011-04-26  
weiqiang.yang 写道
第二个问题,类与包的问题:

我们的项目中一个模块或者子模块要有独立的SERVICE,IMPL,DAO,加上ACTION,MODEL
过去两个项目做了不同的放置方式,
一种是com.part1.a.service.Aservice,com.part1.a.serviceImpl.AserviceImpl,com.part1.a.model.A;
另一种是,
com.part1.a.Aservice,com.part1.a.AserviceImpl,com.part1.a.Adao;
不知道有没有更好的放置方法?
其实这么放都是为了找代码的时候方便快速,但是前者创建了太多的包,基本上每个表都要有4-5个包保存,
后者所有东西放在一起,感觉好像层次感欠缺。
--
我更倾向于第二种方式
com.part1.a.Aservice,
com.part1.a.AserviceImpl,
com.part1.a.Adao
1) 重构方便,不用到处找相关的代码,都在一个目录下,如果要删掉这个功能,那么删掉这个目录就可以了
2) dao可以设置成包可见,对外不可见,避免dao被外部直接调用
3) 至于你说缺乏层次感,我觉得不会,在命名规范(*Service, *Dao)上已经体现了层次,实在不行,可以在内部继续分service,dao目录


恩,过去的代码都是第一种放置方式,后来我整理过一回,都改成第二种方式了,也是出于同样的考虑,不过让我犹豫的是,一直不知道第一种放置方式是谁开始用的,为什么会这么用,有什么好处,如果确实没什么好处,还是倾向于第二种。
5 楼 huangleiatay 2011-04-26  
  首先这些东西没有规范,自己习惯或者公司内部习惯就行。
1. 每个模块放一个package,配置太多,可以分割配置文件
2. 其实是2种都可以。小项目建议用第一种。用那种也和分工有关,比如划分职责是按模块分还是按层分。我看的几个开源的都是按模块划分的。
3.刚开始做项目,我们也都是delA(), updateA()。其实service和dao层处理方法相同,dao层一般会抽出了一个baseDao,你在这里抽出个baseService,我觉得也没问题,也倾向于这么做,毕竟只是为了重用代码,
4.我觉得抽出的baseService中的方法不应该太多,基本和baseDao是一个样子,就增删查改.其他的方法应该很难提炼到baseService中.
5.工具包某个类比如用到了apache-common的包,而你这个项目中又没用到这个类,那么common包自然就不闭导进来。这个东西你得自己判断,就像你用hibernate,除了核心几个包外,其他的包是你自己根据情况判断的。
6.JS放置和包类似。不是那种富客户端的,一般放web-root/js下就可以了。
6 楼 cw550284 2011-04-26  
第二个问题个人觉得是java的软肋,很简单的问题,都要写那么多类,看看ruby,是多么的简洁!但是不那么写,后期维护有困难,唉!
7 楼 s929498110 2011-04-26  
那个。。。struts2的通配符在团队开发中使用啊?
我是发了誓的,不用这东西。
8 楼 szcs10138456 2011-04-26  
难道你做了这么多项目不知道项目管理这项工作吗?建议楼主是用maven和nexus把项目管理起来,把基类弄成jar包,要修改必须经过大家知道后用hudson来构建保持版本的持续前进。做任何事都要有条理!想的要远点而不仅仅局限于现有项目~!希望对你有所帮助,谢谢!
9 楼 totong 2011-04-26  
第一个问题,使用通配符并不能很好的解决问题,Struts2有零配置相关的conversion和config-browser插件应该能解决你的问题
conversion插件有一个属性,可以让不同Action的页面放到不同的目录中
struts.convention.result.flatLayout=false

第二个问题,分包的问题,我个人认为分包的目的主要是为了管理代码,如果一个很小的项目,不分包也一样能做,分包的层次复杂程度应该和项目规模成正比,保证一个包里面的类不是很多就行了

第三个问题,接口是否必要,其实一般项目都可以不使用接口,使用接口的目的我认为有两个,第一,可以降低代码的耦合度,第二,使用JDK动态代理需要接口,对于第一个目的,其实一般的项目降低耦合度并没有太大的必要,一般技术定下来之后,很少需要经常对项目中使用的技术进行替换,有时候替换差不多等于重新写了,第二个目的JDK动态代理可是使用cglib代理进行代替,cglib不要求必须实现接口,项目中Dao和Service可以不需要接口就被AOP

一点个人意见:不是每个实体都需要有对应的Service,现在大家都让Service类处理事务,Dao也要事务,所以很多情况下Service下面并没有业务逻辑代码,只是代理Dao的方法,目的是为了有事务,这样做我觉得有问题,真正有逻辑的方法掺杂在数据访问方法中,比较难找,Service也不是在处理业务逻辑,而是在处理数据访问。声明性事务我觉得可以直接作用在Dao和Service上,根据事务的传播性,可以保证事务正常工作,只对需要的类写Service,那么Action中就需要同时注入Service和Dao,当然这也会带来项目管理上的难度,可能有人会图省事,直接写Dao方法来处理逻辑。



10 楼 tfwin2 2011-04-26  
s929498110 写道
那个。。。struts2的通配符在团队开发中使用啊?
我是发了誓的,不用这东西。

就是因为过去没有用过,现在整理起来,发现很多相同的方法,比如update,save,del都是一样的,所以想用通配符,不过因为包路径和页面路径的问题,没有解决,所以最终放弃了,不过虽然放弃了,还是想看看大家在项目中有没有用过。
11 楼 tfwin2 2011-04-26  
szcs10138456 写道
难道你做了这么多项目不知道项目管理这项工作吗?建议楼主是用maven和nexus把项目管理起来,把基类弄成jar包,要修改必须经过大家知道后用hudson来构建保持版本的持续前进。做任何事都要有条理!想的要远点而不仅仅局限于现有项目~!希望对你有所帮助,谢谢!

恩,maven我一直想学,也粗浅了解过,安装过,但是最终没有用起来,因为当时没有时间好好研究一下,直接应用怕出现问题。现在项目一直是用SVN,开发时候还好,我所遇到的问题就是当新项目建立的时候,由于小公司,项目多而杂,所以工具库建了很多又不规范,始终不能保持各个版本兼容,所以每次都是从最新一个项目去COPY这些东西,导致过于复杂了!
12 楼 tfwin2 2011-04-26  
totong 写道
第一个问题,使用通配符并不能很好的解决问题,Struts2有零配置相关的conversion和config-browser插件应该能解决你的问题
conversion插件有一个属性,可以让不同Action的页面放到不同的目录中
struts.convention.result.flatLayout=false

第二个问题,分包的问题,我个人认为分包的目的主要是为了管理代码,如果一个很小的项目,不分包也一样能做,分包的层次复杂程度应该和项目规模成正比,保证一个包里面的类不是很多就行了

第三个问题,接口是否必要,其实一般项目都可以不使用接口,使用接口的目的我认为有两个,第一,可以降低代码的耦合度,第二,使用JDK动态代理需要接口,对于第一个目的,其实一般的项目降低耦合度并没有太大的必要,一般技术定下来之后,很少需要经常对项目中使用的技术进行替换,有时候替换差不多等于重新写了,第二个目的JDK动态代理可是使用cglib代理进行代替,cglib不要求必须实现接口,项目中Dao和Service可以不需要接口就被AOP

一点个人意见:不是每个实体都需要有对应的Service,现在大家都让Service类处理事务,Dao也要事务,所以很多情况下Service下面并没有业务逻辑代码,只是代理Dao的方法,目的是为了有事务,这样做我觉得有问题,真正有逻辑的方法掺杂在数据访问方法中,比较难找,Service也不是在处理业务逻辑,而是在处理数据访问。声明性事务我觉得可以直接作用在Dao和Service上,根据事务的传播性,可以保证事务正常工作,只对需要的类写Service,那么Action中就需要同时注入Service和Dao,当然这也会带来项目管理上的难度,可能有人会图省事,直接写Dao方法来处理逻辑。




第一个,不希望使用注解,注解过多,可能会导致失控,XML可读性还是好点。不过我会研究一下那两个插件。
第二个,分包的问题其实不是很重要,不过大家的说法让我明白这两种分包的原因了,当工作人员比较多,分工比较细的时候,多包,当开发人员很少的时候,一个包放上几个类更便于开发与维护。目前我们都是小项目,所以我认为后者更适合我了。
第三个,我曾经一度想去掉所有的接口,直接使用实现类,但是由于STRUTS2的参数拦截器的原因,直接使用实现类会报错,所以最后所有的SERVICE还是定义接口了。
不过还有一个定义接口的原因是,当我把接口写好的时候,可以让新员工去写实现类,这样更加可控一些。
第四个,呵呵,事务做的不多,很少遇到需要回滚的业务,以前学过一点皮毛,是学hibernate和spring的时候接触了一些,虽然一直在学习目录上,但是一直没有投入精力,数据库事务比较熟,很多时候写PLSQL解决效率问题。

13 楼 totong 2011-04-26  
引用

第一个,不希望使用注解,注解过多,可能会导致失控,XML可读性还是好点。不过我会研究一下那两个插件。
第二个,分包的问题其实不是很重要,不过大家的说法让我明白这两种分包的原因了,当工作人员比较多,分工比较细的时候,多包,当开发人员很少的时候,一个包放上几个类更便于开发与维护。目前我们都是小项目,所以我认为后者更适合我了。
第三个,我曾经一度想去掉所有的接口,直接使用实现类,但是由于STRUTS2的参数拦截器的原因,直接使用实现类会报错,所以最后所有的SERVICE还是定义接口了。
不过还有一个定义接口的原因是,当我把接口写好的时候,可以让新员工去写实现类,这样更加可控一些。
第四个,呵呵,事务做的不多,很少遇到需要回滚的业务,以前学过一点皮毛,是学hibernate和spring的时候接触了一些,虽然一直在学习目录上,但是一直没有投入精力,数据库事务比较熟,很多时候写PLSQL解决效率问题。


我现在开发一些小项目一般使用grails,这个我感觉在约定优于配置方面做的是很好的,完全没有注解,什么目录放什么东西已经约定好了,我的很多想法都来源于grails
14 楼 JMS_Exception 2011-04-26  
tfwin2 写道
s929498110 写道
那个。。。struts2的通配符在团队开发中使用啊?
我是发了誓的,不用这东西。

就是因为过去没有用过,现在整理起来,发现很多相同的方法,比如update,save,del都是一样的,所以想用通配符,不过因为包路径和页面路径的问题,没有解决,所以最终放弃了,不过虽然放弃了,还是想看看大家在项目中有没有用过。

<action name="*Web" class="web{1}">
			<result name="list{1}">/pages/{1}/list{1}.jsp</result>
			<result name="add{1}page">/pages/{1}/add{1}page.jsp</result>
			<result name="add{1}managerpage">/pages/{1}/add{1}managerpage.jsp</result>
			<result name="view{1}page">/pages/{1}/view{1}page.jsp</result>
			<result name="vestadd{1}page">/pages/{1}/vestadd{1}page.jsp</result>
			<result name="succadd{1}" type="redirectAction">/{1}Web!get{1}list</result>
			<result name="delete{1}" type="redirectAction">/{1}Web!get{1}list</result>

</action>


项目中这样写的 .跳转还是挺灵活 。不过这样写有些方法要规范些
15 楼 gangxueuser 2011-04-27  
类啊,包啊,个人意见:action,manager,service,dao,dataobject之类的,不过好的组织方式,可以让人打开一个工程看package的结构就可以看出来程序的一二来也很爽的。
16 楼 yizhilong28 2011-04-27  
totong 写道
引用

第一个,不希望使用注解,注解过多,可能会导致失控,XML可读性还是好点。不过我会研究一下那两个插件。
第二个,分包的问题其实不是很重要,不过大家的说法让我明白这两种分包的原因了,当工作人员比较多,分工比较细的时候,多包,当开发人员很少的时候,一个包放上几个类更便于开发与维护。目前我们都是小项目,所以我认为后者更适合我了。
第三个,我曾经一度想去掉所有的接口,直接使用实现类,但是由于STRUTS2的参数拦截器的原因,直接使用实现类会报错,所以最后所有的SERVICE还是定义接口了。
不过还有一个定义接口的原因是,当我把接口写好的时候,可以让新员工去写实现类,这样更加可控一些。
第四个,呵呵,事务做的不多,很少遇到需要回滚的业务,以前学过一点皮毛,是学hibernate和spring的时候接触了一些,虽然一直在学习目录上,但是一直没有投入精力,数据库事务比较熟,很多时候写PLSQL解决效率问题。


我现在开发一些小项目一般使用grails,这个我感觉在约定优于配置方面做的是很好的,完全没有注解,什么目录放什么东西已经约定好了,我的很多想法都来源于grails

约定优于配置,如果都遵循规范,是个很好的方案
最大的麻烦在于新老接替。