层的职责的请教

现在后台分成如下几个层:
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中包装,是否太重复和烦琐?
多谢

DAO只负责数据库操作,不涉及任何逻辑

Service就需要业务逻辑了,比如getUserOrder()在DAO,你就查数据库就行,在service中,你可能需要首先验证当前用户是否有这个操作权限,然后调用DAO,最后记录日志

ok
那你的意思是
service的方法 >= dao的方法?
这样会不会存在我上面说的繁琐呢

>需要在dao中定义,daoimpl中实现,service中包装,是否太重复和烦琐?
其实这不会发生,因为你认为getUserByAreaSrv()方法肯定一定要完全从数据库完成,其实不然,其实我可能只从数据库查询一个ID集合,然后,在服务层再通过缓存访问封装成完整的Model。这些都需要在Service完成(只是一个比喻)。

预留Service是为防止你的业务系统复杂化之后有一个插脚的地方。

现在很多系统就没有这种插脚的地方,在struts的Action中直接调用Hibernate数据库操作,如那个日本人做的开发框架RoR就是这样,这些以丧失可维护性做代价的快速开发都是伪框架。

所以,为你的系统将来留着Service。


明白了
所以现在对于这个方法在dao中定义还是在service中定义
问题都不大
好比那个方法,可以在daoimpl中直接操作sql来实现
也可以在service中通过缓存什么的来实现
并不重要

关键在于,service的存在,是为系统扩展留下的后路?
是不是这个意思?

我认为Dao层还是不要暴露在最外层为妙,即Service以外的层次都无法调用。否则实体化与应用逻辑以及界面之间的耦合度将无法控制,导致产品的生命周期缩短,可扩展性遭到破坏。
Service层当然也可以有getUserOrderByID() 这样的操作,但最好通过调用DAO来实现,或者像banq说的以dao-cache的方式来实现,而不是直接去做实体操作。这样做可能会感掉有些重复繁琐,但会给产品今后的升级补充带来好处。可能会多出这30%的代码量,但带来的好处是起码能延长代码30%的生命。
Service的方法定义和方法内的参数定义更倾于业务逻辑,而不是存储方式。而Dao的定义则跟存储方式直接挂钩,而不需要过度考虑业务逻辑。所以代码上的“繁琐”恰恰代表了逻辑上的“简单”。

更重要的是Service是必须的。

一般service层是怎么实现的?是不是就是一个拥有很多静态方法的类,每个静态方法处理一些业务逻辑,还是有什么其它的方法,望指教

我现在的实现很简单,因为还没有真正的业务逻辑在里面
public class CoreFeeService
{
private CoreFeeDao feeDao = null;

public CoreFeeService()
{
super();
feeDao = new CoreFeeDaoImpl();
}

public CoreFeeService(CoreFeeDao feeDao)
{
super();
this.feeDao = feeDao;
}
public List<CoreFee> getFeeByNumber(String feeNumber)
{
return feeDao.getFeeByNumber(feeNumber);
}
............
}

我还有疑问,比如CoreFeeService好像是操作CoreFee这个domain bean的,如果我有一段业务逻辑,是调用CoreFeeService改变CoreFee的一些属性,然后将CoreFee持久化到数据库,接着可能要调用另一个domain bean的service方法。

在Struts框架中,这段代码是写在Action中,还是别的地方,Action又好像应该只控制转发,不应该有业务的代码在里面。但像上面那样,可能还有事务处理,这时我该怎么做好呢?

你描述的这段设计本来就是包含了业务逻辑。当然应该在Service里。service本身包含了粒度不同的操作,粗粒度的操作(方法)里可以包含很多细粒度的操作。这些细粒度的操作可以是private,也可是是public(如果别的action需要它)。
Action的概念当然跟业务本身是有一定关系的。你可以在action的代码中表示出一些业务上的逻辑关系,但要节约。能在service中实现的最好在service中。这对程序结构是有好处的。
你说:“Action又好像应该只控制转发,不应该有业务的代码在里面”――这句话体现出你可能已经成为“框架”的“受害者”了。要用“框架”来提炼你的设计,而不要用来约束你的思维。不要指望从“框架”中找到理清软件开发一切思路的“银弹”――因为它根本不存在。

各位的观点让小弟受益非浅,偶还是一个新手,还有很多东西要向各位前辈学习啊

以前在Action中写了许多业务代码,结果在复用的时候只能是粘贴拷贝,偶觉得很是不好,也不好维护,现在正在修改中,各位的观点很值得借鉴

感觉service有点象facade啊

本人是初学的,觉得软件发展到现在为什么要出现分层,最主要目的是在不同的层中观注不同的问题域,从而来提高软件的逻辑清晰度及将相同性质的问题统一管理。分层会增加软件设计的复杂性,但是可以使软件的逻辑更加清晰,在软件的生命周期中更快速地找到设计的缺陷。不同的层次所处理的问题域不同。
跟据楼主的说法本人就将其分成三层
持久层(Dao:接口,定义了持久化方法,CRUD DaoImpl:Dao的实现)
数据层(Domain:提供getter/setter)
控制层(Service:业务逻辑)
楼主在dao中定义了getUserOrderByID() getAllUserOrder() insertUserOrder() updateUserOrder() delUserOrder()五个方法其中getUserOrderByID() getAllUserOrder() 两方法是持久化的需要如果不能跟持久化扯上什么关系最好也把他定义到数据层,而后面的<根据地区查询客户getUserByArea(),或者 根据产品线和地区查询客户 getUserByAreaSrv()>这应放到数据层中,他关注的问题只是数据,而要实现他的业务逻辑还需其他的业务类来调用,为什么想到的是放到Service中,那为什么要提供Domain这个东东呢。
对于第二个问题,楼主这样子想,我还是觉得他把Domain忘记了,DAO如果只是用来持久化的,就不应来提供业务数据,而应放在Domain中。
请注意分层是程序员在不同的层面关注的问题的,如果各层面关注的问题不能清楚的划分,那分层一点意义都没反而反会增加程序的复杂性。楼主是将持久化跟数据层混到一起了,如果这样子不影响解决问题了也是可行的,技巧技术在小型系统中反而会使问题复杂化。

>感觉service有点象facade啊
Service是类的性质,Facade是组织类的方式,一个象小组成员;一个是小组管理方式,不一样。

很多人都习惯使用Facade组织Service,其实这不是最好方案,目前适合的就是通过Ioc组织。

1.客服端请求响应层
2.服务层
3.数据持久层
上面三个层中业务层是相对稳定的,当然前提是再需求不变的情况。所以业务层应该包含了所有完成需求所需要的功能。
数据持久层是服务层引申出来的。服务层完成业务操作,需要持久化数据或取回已持久化的数据,所以会抛出持久化(数据访问)需求。数据持久层的职责就是满足服务层抛出的持久化(数据访问)需求。所以对于业务层来说,不关心持久策略是什么,只关心有没有满足它的持久需求。按照这样的思路来保证持久策略的可变性。
服务层+数据持久层组成了的业务服务。访问服务是通过服务层访问。服务层会将全部服务功能发布出来。并且这个业务服务是可重用的。
用户要利用系统来完成业务,目前还缺少用户接口,这就需要客服端请求响应层。客服端请求响应层职责是接受并解析客户端请求,根据解析的结果使用服务,并将使用服务的结果响应给客户端请求。
-----
dao中定义了getUserOrderByID() getAllUserOrder() insertUserOrder() updateUserOrder() delUserOrder()五个方法
------
这五个方法都是由于服务层完成业务功能时的需求,所以数据访问层必须实现。如果业务操作中没有删除客户资料的业务,也就意味着不需要删除客服资料的业务功能,那么,就没有删除用户资料的持久操作需求,DAO中也就没有必要实现delUserOrder()
-----
现在需要一个 根据地区查询客户getUserByArea(),或者 根据产品线和地区查询客户 getUserByAreaSrv()
------
这也是一个业务需求,所以对应系统的服务层也必须要求有相应的业务功能,也就会有相应的持久化需求,DAO也必须实现相应的持久操作。

服务层中抛出的持久需求,有很多是可以合并的,比方说上面根据地区或根据产品线查询客户,这两个就可以合并为一个综合查询的数据访问接口。