编程语言

img smallfox

项目实践点点滴滴

发表于2004/9/27 20:22:00  1251人阅读

分类: J2EE学习实践

1) 先HTML再JSP
web application对客户来说就是一堆html的集合,做出一个html样本既能让客户及早调整需求,也易于将来用html+struts转化

2) Reusable Design
可以把很多共同特性写成可复用系统,它们有超于当前项目的地位,由高手负责设计实现和维护,这样的模块可以找到很多,比如内部搜索(含底层的sql search engine也可复用),角色资源权限系统

3) Don't reinvent the wheel
Jarkata Commons项目拥有众多出色的实用jar,从出名的digester,BeanUtils,DBCP,Collections到Codec,IO,Net,FileUpload,HTTPClient能利用的资源太多了,好好学习非常受用

4) 显式的和分层次的异常声明
如果一个method可能抛出DaoException,NoDataFoundException,AppException,UnexpectedException,那么需要全部列出不能在方法声明出直接写 throw Exception { ... } 另外我觉得j2ee项目,每一个层次需要定义两层exception(在逻辑上,非必要),一层是内部使用,一层与上下层交互,比如java.rmi.RemoteException就是一种较高层次的异常,所有细节层次的异常在出这个层的时候应该用exception的initCause()方法包装再抛出。

以上所说的分层次也并非必需,但在大部分情况下一个完整的exception体系需要建立,如web app有一个叫ApplicationException作为所有被这个application内部抛出的异常的super class,这样在某个层次,如果必要,程序就可以catch appException继而完全避免这些可预见的异常,当然与此对应的unexpectedException当然就不需要application处理。常见的ApplicationException有InvalidParameterException, DaoException, NoDataFoundException, TooLargeResultsetException, OptimisticLockingException等等。为了方便管理和使用(前端报错需要),每个exception最好有一个ID和一个String类型的field用于说明真正出错原因

5) VO/DTO的应用(Value Object, Data Transfer Object)
就我的理解VO/DTO的作用并不在于简化程序,倒在于降低耦合。其实有些时候VO的使用挺烦的,它的好处在接口要改动时才会体现,使得一个人不用通读另一个的代码而只要照着VO/DTO更改即可。我现在的项目VO主要用于Action<-->EJB之间,总的来说没什么大的问题。
我不清楚应用了hibernate后会怎样,只是当前在我们的ibatis实践中,专门加了对于主要entity的VO,让ibatis将数据库获取的结果直接映射进VO entity再返回,用处不小

6) 事务处理
EJB容器可以自行管理事务,那么每个EJB Call都将是一个Transaction,这个特性实在吸引人。
下面是一个ejb-jar.xml的片断
    <session>
      <display-name>AccountCodeMgr</display-name>
      <ejb-name>AccountCodeMgr</ejb-name>
      <home>com.medlog.business.parasetting.AccountCodeMgrHome</home>
      <remote>com.medlog.business.parasetting.AccountCodeMgr</remote>
      <ejb-class>com.medlog.business.parasetting.AccountCodeMgrEJB</ejb-class>
      <session-type>Stateless</session-type>
      <transaction-type>Container</transaction-type>
    </session>

在没有ejb的时候,以ibatis为例,可以用以下方法在baseDAO里实现Transaction处理
constructor() { sqlMap = SqlMapUtil.getInstance().getSqlMap(); }
startTransaction() { sqlMap.startTransaction(); }
endTransaction() { sqlMap.commitTransaction(); sqlMap.endTransaction(); }
rollbackTransaction() { sqlMap.endTransaction(); }
剩下的就好处理了。

7) Fast Lane Reader Pattern for DAO 外交快速通道??
EJB的初始化,jndi查找以及事务管理都附带一笔额外的开销,所以在前端只需浏览而不需改变数据库内容的时候,我们应用了Fast Lane Reader模式,action照样把业务交予Business Delegate处理,而BizDelegate根据是否改变数据库做出判断,如果答案肯定,它会将请求交给EJB处理,但若只是view,BizDelegate会直接唤醒dao执行select操作,从而绕过ejb层加快速度

8) BusinessDelegate和EJB的参数检查
还是因为EJB有overhead,经常在bizDelegate层就要进行一次参数检查,如果有错直接返回InvalidParameterException, 不浪费EJB资源,但是还存在这样一种可能,EJB_A called EJB_B with a set of invalid inputs, 这样的情况使得EJB层还需要再复查参数,虽然这样会有重复,但这种overhead毕竟不可避免

9) WebKey的应用
定义一些公用的jsp+actionrequest/session的attributeName,.让程序可读性更高,因为大部分情况下一个请求都不需要用到5个以上的attributes,所以我们可以有:
USER_VO_KEY,USER_ROLE_LIST存用户信息,MENU_ITEM_LIST存菜单项,SEARCH_CRITERIA_ONE(~FIVE)存搜索条件,SEARCH_RESULT_LIST_ONE(~FIVE)存结果,LIST_ONE(~FIVE)和OBJECT_ONE(~FIVE)存其他信息。毫无疑问代码可读性大大提高,只是我还在考虑是否有更好的方法,毕竟webkey还是摆脱不了初级程序员随便乱加/乱给各object赋值的恶梦

10) Optimistic Locking
我现在做的项目也用到了OptLocking的思想,简单说有几点,第一我们假设每一个用户在update前都会查看数据,或者说我们的网页设计使得frontend每一个可能的数据改变之前都有一个相对应的查看(select)操作. 基于此,我们限定了如果某数据D在用户A看后被另一用户B改动,那么用户A接下来对D的更改请求将被退回(with a special exception),而要求A重新查看数据再更新。如果这一个假设和限定都满足,可以有以下方法保证数据的更新是按顺序依次生效的 <1>每个需要的表加入lastUpdatedOn域 <2>每次select时选出该字段供待会儿update使用 <3>update时加入where lastUpdatedOn=#lastUpdatedOn# 这样如果用户B改过了某数据,他一定也改过了lastUpdatedOn,这样用户A用带where lastUpdatedOn=***的update就不可能真正更改到任何数据,frontend也可以根据此(updatedCount=0)用js提醒用户

--==欢迎大家跟贴就该文章和感兴趣的话题和我讨论问题==--

阅读全文
0 0

相关文章推荐

img
取 消
img