BPP项目 HT 部分完成小结:
1、Action 类怎么写?
现在的做法是Action 层直接与 dao 层耦合,所有的功能都在 Action 类中完成。
缺点:如果 Action1 与 Action2 两个类有部分功能重复,在“避免重复代码”这样的原则下, Action2 类会实例化一个 Action1 类然后调用其方法。这样就要求 Action1 的该方法为public 修饰,这就与action 的方法是相同的修饰,会使得该Action 类的功能(提供的action)混乱。这样显然不好!而且所有的功能都在 Action 类中,这样 public、private 的方法必然混在一起,混乱不清!
建议修改:增加一个service 层。
Action 类的 public 方法全部为 action(这样一眼就知道该 Action 类有哪些具体的action),其内部实现细节交给 service。当然Action 类也是有一些私有方法——处理 field 域与页面间的参数传递。(如 ManualInputWeightAction 的 initFirstManualInputParams( )方法, initContinueManualInputParams( ) 方法)对于重复的功能,重复使用service,而不是Action。
注意:这里的dao层不时 iBatis提供的dao 层,而是和业务具体相关的操作。
优点:方便测试 business 层的类,因为可以很容易的 Mock 一个dao 类对象的操作。
建议:如果 Action 类有多个action,那么就不要使用默认的 execute( )方法。而是每个方法指明其功能(好的方法名)。
2、action 怎么配置?
不要将所有的action 配置在一个<package/>里,要根据不同的“功能模块”配置不同的<package namespace="/ 功能模块名" />。这样容易查找,也可以避免命名冲突。“功能模块”的名称要尽早取,也要与 Action类的包名保持一致。
3、怎么写与DB相关的测试?
如果是直接构造数据,然后插入DB。第一操作肯定是可以,但是第二次呢?这样做显然不适合单元测试。
如果采用每次测试前构造DB数据(static 方式),测试完后即清空。这样适合单元测试,不过就是效率问题。
再则采用EasyMock 的方式。
4、怎么传递参数?
阶段1,获取jsp页面参数,action 提供set方法;添加如下注释:
// from jsp params
阶段2,action提供参数给jsp页面显示,action提供get方法。添加如下注释:
// show to jsp params
阶段1-2,action提供get / set 方法。添加如下注释:
// from jsp to jsp params注意:如果Action 类有太多的field 供jsp页面显示,那就封装一个JavaBean,避免Action 类太混乱。
5、查询数据部分(注意效率)
a、不要将全部数据都取出在计算或显示,一定要缩小范围,只取当前有用的最小集合。
b、能用select 语句完成的,尽量用select 语句完成(如,SUM、MAX、MIN、AVG....)
6、多用户数据操作,数据不一致问题
例如:用户A 和用户B 同时对某条记录的
(A)修改-(B)修改 操作 用户B没看到用户A 的修改操作,可能导致数据不一致
(A)修改-(B)删除 操作 安全
(A)删除-(B)删除 操作 安全
(A)删除-(B)修改 操作 一定错误(应该给错误提示)
7、action 与 business 的对应关系
多个action 对应一个business(如下图)。
优点:明确参数的传递——哪个action需要哪些参数(传递进来的或返回出去的)
strut2框架下对应的 get / set 方法就会少。
8、缓存 sqlMapClient 时应注意的问题
BPP 项目中,为了优化性能缓存了 sqlMapClient 对象(根据 companyId 对应一个DB 的 schema)。
但是这样存在一个隐藏的风险:
1、当修改了 schema 链接用的用户名或密码,使用缓存的 sqlMapClient 显然会出错。
2、删除了该 schema 但是又为该 companyId新建了一个对应的 schema,使用缓存的 sqlMapClient 也错误。
解决办法:使用缓存的 sqlMapClient 对象之前,测试其有效性。有效,就使用;无效,新建一个再使用。