现在后台分成如下几个层:
Domain:提供getter/setter
Dao:接口,定义了持久化方法,CRUD
DaoImpl:Dao的实现
Service:业务逻辑
但是在实际的过程中发现,service里面有很多涉及到持久化的查询、更新操作,那么,这些方法是在dao中定义呢?还是在service中定义和实现?
比如,对于一个 客户资料UserOrder 实体
dao中定义了getUserOrderByID() getAllUserOrder() insertUserOrder() updateUserOrder() delUserOrder()五个方法
现在需要一个 根据地区查询客户getUserByArea(),或者 根据产品线和地区查询客户 getUserByAreaSrv()
这样的方法,定义在service还是dao中?
第二个问题。service层肯定是面向客户端调用的,那么dao层对于客户端是否暴露?
就是说,service层中是否提供dao中的方法,比如getAllUserOrder() insertUserOrder()这些方法?
如果不提供,那么客户端需要知道哪些是dao中提供的,哪些是service提供的
如果提供这些方法,意味着所有的方法需要在dao中定义,daoimpl中实现,service中包装,是否太重复和烦琐?
1.
DAO只负责数据库操作,不涉及任何逻辑,Service就需要业务逻辑了,比如getUserOrder()在DAO,你就查数据库就行,在service中,你可能需要首先验证当前用户是否有这个操作权限,然后调用DAO,最后记录日志
2.需要在dao中定义,daoimpl中实现,service中包装,是否太重复和烦琐?
其实这不会发生,因为你认为getUserByAreaSrv()方法肯定一定要完全从数据库完成,其实不然,其实我可能只从数据库查询一个ID集合,然后,在服务层再通过缓存访问封装成完整的Model。这些都需要在Service完成(只是一个比喻)。
预留Service是为防止你的业务系统复杂化之后有一个插脚的地方。
现在很多系统就没有这种插脚的地方,在struts的Action中直接调用Hibernate数据库操作,如那个日本人做的开发框架RoR就是这样,这些以丧失可维护性做代价的快速开发都是伪框架。
所以,为你的系统将来留着Service
3.我认为Dao层还是不要暴露在最外层为妙,即Service以外的层次都无法调用。否则实体化与应用逻辑以及界面之间的耦合度将无法控制,导致产品的生命周期缩短,可扩展性遭到破坏。
Service层当然也可以有getUserOrderByID() 这样的操作,但最好通过调用DAO来实现,或者像banq说的以dao-cache的方式来实现,而不是直接去做实体操作。这样做可能会感掉有些重复繁琐,但会给产品今后的升级补充带来好处。可能会多出这30%的代码量,但带来的好处是起码能延长代码30%的生命。
Service的方法定义和方法内的参数定义更倾于业务逻辑,而不是存储方式。而Dao的定义则跟存储方式直接挂钩,而不需要过度考虑业务逻辑。所以代码上的“繁琐”恰恰代表了逻辑上的“简单”。
更重要的是Service是必须的。
22一般service层是怎么实现的?是不是就是一个拥有很多静态方法的类,每个静态方法处理一些业务逻辑,还是有什么其它的方法,望指教
1我还有疑问,比如CoreFeeService好像是操作CoreFee这个domain bean的,如果我有一段业务逻辑,是调用CoreFeeService改变CoreFee的一些属性,然后将CoreFee持久化到数据库,接着可能要调用另一个domain bean的service方法。
在Struts框架中,这段代码是写在Action中,还是别的地方,Action又好像应该只控制转发,不应该有业务的代码在里面。但像上面那样,可能还有事务处理,这时我该怎么做好呢?
2你描述的这段设计本来就是包含了业务逻辑。当然应该在Service里。service本身包含了粒度不同的操作,粗粒度的操作(方法)里可以包含很多细粒度的操作。这些细粒度的操作可以是private,也可是是public(如果别的action需要它)。
Action的概念当然跟业务本身是有一定关系的。你可以在action的代码中表示出一些业务上的逻辑关系,但要节约。能在service中实现的最好在service中。这对程序结构是有好处的。
你说:“Action又好像应该只控制转发,不应该有业务的代码在里面”——这句话体现出你可能已经成为“框架”的“受害者”了。要用“框架”来提炼你的设计,而不要用来约束你的思维。不要指望从“框架”中找到理清软件开发一切思路的“银弹”——因为它根本不存在。