`
kakac001
  • 浏览: 12655 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

请教关于domain对象注入service

阅读更多
在一个domain对象中,
注入相关的service,不知道这样的设计是好还是坏。
因为这个service是这个domain对象的某个行为不可缺少的一部分.

举个例子,
在User这么一个domain对象中,
需要有一个支付这么一个行为,暂时称它为pay
在pay的时候,需要调用相关的service来完成支付的操作.


public class A{
  private PayService payService;
  
  public void pay(){
    payService.doPay(this);
 }
}



不知道这样的设计是否存在问题..
如果有问题的话,又应该如何设计呢.
本人小菜一个,望各位大大不吝赐教
分享到:
评论
48 楼 murainwood 2009-03-19  
这种事情还是少做为好,不给自己惹麻烦是其次,更重要的是不要给别人惹麻烦
47 楼 whitez 2009-03-19  
建议楼主看看之前论坛讨论过的domainmodel的相关帖子,我觉得楼主所说的就像贫血和充血的问题,domain object和domain logic的问题。
46 楼 karlineo 2009-01-29  
其实为什么要引入Service呢?本身就必须看实际的情况。可能为了易用性,隐藏细节等等(facade,adapter),有时加一个中间层可以起到facade的作用,这种通常是application service,而对于domain service多数是分配职责的时候,找不到一个合适的实体类,才虚拟一个无状态的service出来,把职责分配给这个service,而你可以不命名为什么service。楼主这里的问题是,pay怎么是user的方法,同时又是pay service的方法呢?而你这里只是把它代理出去,难道有user的pay和没有user的pay不一样?如果pay需要调用user的数据,可以考虑把user作为参数传给pay(user)。
我个人是倾向充血的,是否好的设计只能够在实际问题当中考虑,设计本来就是循序渐进的演化,而不是一开始就定死的,所以随便就说这样耦合性增大,明显是没有理由的。不好 控制 取决于你切分边界的好坏。
本来就没有silver bullet,我只是发表一下看法。请 高手 指教。
45 楼 karlineo 2009-01-29  
我觉得很多时候pay不是user的行为,你究竟是pay什么呢?pay bill,pay order还是pay 什么其他呢?如果让我去考虑一个问题,我会先确定实体类,一开始是数据和行为结合起来的,关注于实体类的时候,先不考虑数据库,因为那个session state和persistent state的同步问题是和技术相关的(甚至用后台进程来同步)。确定职责通常都是谁有数据,谁处理。倘若这时候应用比较复杂,可能这样做会导致某些类过于大,或者层次结构过多,这时候才会考虑其他的策略,然后把某些行为代理出去或者把数据和行为分开。到最后这个职责分配给了谁?是看系统的复杂度的。但是起点都是,谁有数据,谁处理。只不过由于要综合权衡可重用性,易用性等等因素,一个原来简单的设计慢慢演化到后面变成复杂的设计,这种设计的推进导致某些职责被分配出原来那个拥有数据的类。而不会一开始设计就已经定死了pay有个pay service,专门做pay,一开始的设计怎么会知道为什么会有这个类呢?不看实际情况就按着某些分层的做法来套,往往会导致复杂度过高,而且不值得这么做。到最后由于增加了复杂度,导致晕头转向,都不知道职责怎么分配了(还怎么分而治之呢)。
44 楼 88250 2009-01-27  
厄。。。。Java 的 DDD 讨论还在持续啊- -,请 LZ 参看 从大概 05 年至今在 JavaEye 上的相关讨论,你就可以找到你问题的答案了 :-)
43 楼 抛出异常的爱 2009-01-25  
jiayouyx 写道
抛出异常的爱 写道
dmain.startTransaction();
dmain.dosomthing();
dmain.getFoo(foo);
dmain.endTransaction();

这样子写代码是不是有点傻?



DMAIN里实现了这些操作?还是引用了别的层的方法?

引用加继承
本想把代码改成这个样子.
连接池是单实例的.......

但看看也非常恶心所以就不来了.
42 楼 jiayouyx 2009-01-24  
抛出异常的爱 写道
dmain.startTransaction();
dmain.dosomthing();
dmain.getFoo(foo);
dmain.endTransaction();

这样子写代码是不是有点傻?



DMAIN里实现了这些操作?还是引用了别的层的方法?
41 楼 jiayouyx 2009-01-24  
为何要这样做?目的只有一个,做出一个可以维护的系统。好,这是我们的目的。那么我们到底怎么样去设计它,现在是我们的难题。LZ提这个问题,似乎也有点不太清楚服务层为什么需要这样做。(原因很多,分层,封装上下边界,之后在服务层内直接调用类似于API的操作 …… ……)

其实很简单啊:
LZ,你的领域逻辑是哪些?你的技术逻辑又是哪些?好,先搞清楚PAY这个操作到底属于什么。
为什么要这样设计,在服务层里直接调用DAO层的操作,目前来说DAO的设计是否合理?等等。没有DAO,不知道项目的大小和领域复杂度,光靠一个服务层基本上不能断定你的这个设计是好是坏。

大三小菜鸟。有错别把我批的太惨就行,呵呵!
40 楼 抛出异常的爱 2009-01-20  
dmain.startTransaction();
dmain.dosomthing();
dmain.getFoo(foo);
dmain.endTransaction();

这样子写代码是不是有点傻?
39 楼 pipilu 2009-01-19  
还是就楼主的疑问。我感觉自己之前的回复有些片面了。
面向对象不仅仅单纯的是:某个对象有哪些属性和行为,把这些属性和行为封装到一个类里——认为这就是面向对象了。
一个程序是否是面向对象的设计,还需要考查它是否符合:单一职责原则、开放封闭原则、依赖倒置原则等设计原则。
这说开了就太大了,我就捣一下乱吧。
38 楼 抛出异常的爱 2009-01-19  
kakac001 写道
抛出异常的爱 写道
当一个业务逻辑包含了N个表,N个DAO,N个逻辑关系
N大于5时
125种组合......
人的脑子一般是思考不过来的.
用domain封来封去....事务,边际变模糊了.......
最后都放到action里去作事务.


呵.貌似大部分人都推荐用单纯的service来做.
原本是想说pay作为User的一个行为,会更oo一些.

昨天也有就这个问题请教了下一位牛人.
是这样的看法,这个问题目前没有一个绝对的准则来说是好是坏,
各有利弊,需要自己去权衡.
作为他本人,他也是比较不倾向于充血.
也正如异常这边说的,这样的耦合性大了许多.
之后可能不好控制

呵..谢谢大家了..

前几天遇到一个问题.
需要把cookie的user用户的一些属性传到dao中去.
中间service一点没用上.
改了三个类之后恶心的厉害......
测试又没办法测,
传过去又没什么大用.
不如把内容放在用户中
把用户传到后台去
想想还是不能免俗

还真是没有dmain没办法
圆满完成这种杂技动作
37 楼 steven_cheng 2009-01-19  
zzq230 写道
其实lz讲到了一个 domain和 service如何切分的问题?
Service业务逻辑与Domain业务逻辑切分的原则
两种原则:
1. 领域模型只包含了不依赖于持久化的领域逻辑,而那些依赖持久化的领域逻辑被分离到Service层。
2. 使用Rod Johnson的”case by case”原则。可重用度高的,和domain object状态密切关联的放在domain中,可重用度低的,和domain object状态没有密切关联的放在Service中。

我觉得我同意这个说法
带持久化的逻辑还是不要放在domain object里的好
36 楼 volking 2009-01-18  
你说的domain是什么
35 楼 ayaga 2009-01-16  
我的做法是:
1.domain中只定义属性,getter,setter,所谓贫血模型。
2.在service层注入dao,对数据进行操作。
3.struts2+spring可以把action作为service层,只要自己继承一个继承自ActionSupport的父类,以后容易移植。
4.使用spring+hibernate可以写一个公共类,实现dao层是一个只有一个类的层。
34 楼 heavener 2009-01-15  
可以这样,但是软件分层就不明显了吧,你理解了并不代表团队其他人能理解。而且这样我觉得也不是很通用。可能会造成很多重复代码。重构性不是很好。
33 楼 402king 2009-01-14  
虽然大家有点烦EJB,但他里面的entity(特别是ejb3以后),和session的关系和你讲的关系有点相似哦。
实体和操作分开也是sun的选择。

说的不对的,荒淫大家拍砖
32 楼 seele 2009-01-14  
domain 当作是个体行为。。。

service 当作是群体行为。。。。

这么区分就可以了
31 楼 wuxiaoq 2009-01-13  
kakac001 写道
嗯.了解了. thx

题外话..这些“法则”有哪里有专门的介绍吗?


http://cavingdeep.cnblogs.com/archive/2004/10/28/208956.html
30 楼 zzq230 2009-01-12  
其实lz讲到了一个 domain和 service如何切分的问题?
Service业务逻辑与Domain业务逻辑切分的原则
两种原则:
1. 领域模型只包含了不依赖于持久化的领域逻辑,而那些依赖持久化的领域逻辑被分离到Service层。
2. 使用Rod Johnson的”case by case”原则。可重用度高的,和domain object状态密切关联的放在domain中,可重用度低的,和domain object状态没有密切关联的放在Service中。
29 楼 langds 2009-01-12  
建议楼主这样抽象,把pay也划一个域出去,同时也不要在user里出现pay动作。而是把pay动作放到外面的领域服务层去。
具体划分就是这样:
Payment ----依赖--->User(领域对象包内依赖,这个是内聚)

下面是从领域服务层到领域对象的依赖:
UserService--依赖--->User
PaymentService--依赖---> Payment

另外还可以出现类似这样的服务,同时依赖下层的两个领域对象:UserPaymentService --->User, Payment
这样一样层次就清楚了,行为不也内聚了吗?

欢迎拍砖

相关推荐

Global site tag (gtag.js) - Google Analytics