论坛首页 Java企业应用论坛

要领域模型干嘛?

浏览 45163 次
该帖已经被评为良好帖
作者 正文
   发表时间:2008-11-27  
嗯,例子完全make sense。我归纳出一条:
如果一段逻辑,只是修改entity自身的状态,没有外部依赖(比如需要数据库连接,网络访问),那么就应该放到entity自身去。
有外部依赖的代码放到service之中。
这个是不是你的原意呢?

但是这样的归纳是从结果出发的,因为框架和我的设计需要我这样,所以就这样。如果从value出发呢?把逻辑放到domain中的价值是什么?放到service中的价值是什么?
0 请登录后投票
   发表时间:2008-11-27  
我说下我的自己的看法和理解哈:
我的观点是value 和logic 分开:
    domain object应该保持十分简单,就只保存value,其他逻辑一点不要.
    service类里面写业务逻辑, 不保存业务相关的值.

我拿一个饭店例子现实例子来类比软件模型:
   1. 服务员 相当于 action
   2. 取菜窗口相当于业务接口 service classes
   3. 各种各样的原材料,采购单等等属于 domain object

action 是面向顾客的,可能是为到点里面顾客服务的,也可能是送外卖的 所以action要独立出来就是为不同的客户服务,满足提供不同的服务流程.
service classes 是负责核心的业务逻辑的实现,有了它服务员就不用管饭菜是怎么做来的.这样不同的服务员都可以重用相同的业务逻辑.
而domain object就是整个业务流程中被处理的对象,我觉得不应该包含业务逻辑, 如果domain object包含了业务逻辑的话,比如说 "Money" 这个domain object.他本身对其他的业务对象不了解,而很多业务逻辑都需要众多的domain object的参与,如果domain object包含业务逻辑,那么各个domain object的耦合性就大了,而且不易理解,比如 Money 知道了自己去换成猪肉一样 匪夷所思! 所以我人物不能在domain object 里面包含业务逻辑


这是我的看法.thanks
0 请登录后投票
   发表时间:2008-11-27  
kaipingk@gmail.com 写道

    domain object应该保持十分简单,就只保存value,其他逻辑一点不要.
    service类里面写业务逻辑, 不保存业务相关的值.


domain里应该包含大部分业务逻辑,而Service才只是薄薄的一层,Service是客户的接口,它调用相应domain和repository来完成功能,业务逻辑由domain来完成,repository负责持久化逻辑(包括存储和查询),我个人不太建议domain负责持久化逻辑(这应该就是所谓的充血模型吧)。
0 请登录后投票
   发表时间:2008-11-27  
downpour 写道
taowen 写道
能放在domain中的代码与能放在service中的代码是有区别的。如果你只是抽象的说,500行代码,那就没有什么好讨论的了。或者把你所说的无状态的领域逻辑下个定义?我的问题就是什么样的500行代码在domain中,什么样的500行的代码在service中。根本上来说,你把代码写到domain中的动机是什么,只是给你500行代码找个地方放吗?那我建一个xxxHelper,xxxUtils不也一样吗?同样,代码写到service中的动机是什么,为什么要放在那,不能放到别的地方。


好吧,非要这样说,那我给你用代码举个例子:


// 注销某个用户
public void xxx(User user) {

   // 一大堆其他的逻辑

   // 更改用户状态
   user.setDisable(true);
   user.setLastUpdateDate(new Date());
   user.setLastUpdateBy(this.getCurrentUser());
   
   userDao.update(user);

}



可以改成:


// 注销某个用户
public void xxx(User user) {

   // 一大堆其他的逻辑

   // 更改用户状态  
   user.disable();

   // 如果使用hibernate,可以省略 
   userDao.update(user);

}




// 注销某个用户
public void disable() {
    this.setDisable(true);
    this.setLastUpdateDate(new Date());
}



这样你觉得是否满意?


这种做法是对的,大部分逻辑应该放在domain中,service只是个协调者,它调用多个domain,并将实际功能委托给domain。
0 请登录后投票
   发表时间:2008-11-27  
我认为区分充血模型和贫血模型应该以将大部分业务逻辑放在domain中还是放在service中来区分,而不是应该以是否将持久化逻辑放在domain中来区分。DDD赞成将主要业务逻辑放在domain中,从这点意义上来说,DDD使用的实际上就是充血模型。
0 请登录后投票
   发表时间:2008-11-27   最后修改:2008-11-27
taowen 写道
嗯,例子完全make sense。我归纳出一条:
如果一段逻辑,只是修改entity自身的状态,没有外部依赖(比如需要数据库连接,网络访问),那么就应该放到entity自身去。
有外部依赖的代码放到service之中。
这个是不是你的原意呢?

但是这样的归纳是从结果出发的,因为框架和我的设计需要我这样,所以就这样。如果从value出发呢?把逻辑放到domain中的价值是什么?放到service中的价值是什么?


如果将主要业务逻辑放在service中会发生什么?你所称的domain就是一些不带任何方法的数据容器(除了get和set方法),这还叫domain吗?service是无状态的,里面充满了业务逻辑,这不就是Martin Flower称为"Trasaction Script"吗?这完全就是过程化的设计,service的唯一作用就是将一些相关的服务组织在一起。

而将业务逻辑放在domain才是真正的OO设计,能够充分利用OO的特性,封装、多态等,这样才不枉使用Java来开发。

可惜的是在现在大部分Java程序员仍然使用的是过程化的设计,尤其是在做web开发时。

p.s. 我说得不够好,我希望大家都能看下《POJO in Action》。
0 请登录后投票
   发表时间:2008-11-27  
物理学中有三种东西:背景, 结构, 动力学
0 请登录后投票
   发表时间:2008-11-27  
这个东西和采用的技术和框架高度相关:

1、如果你用的是Spring,没啥说的,必须贫血,你想充血也充不起来;

2、如果你用的是RoR,也没啥说的,直接充血,你想贫血也未必贫得下来;

3、JBoss Seam其实已经开始从贫血模型向充血模型过渡,我还是比较看好Seam的。

如果脱离具体的场景谈抽象的领域模型,没太多可谈的,因为已经无所谓贫血不贫血的,你在抽象的设计阶段一定是领域模型驱动的,而不是TransactionScript驱动,甚至现在也不是table schema驱动。
17 请登录后投票
   发表时间:2008-11-27  
taowen 写道
嗯,例子完全make sense。我归纳出一条:
如果一段逻辑,只是修改entity自身的状态,没有外部依赖(比如需要数据库连接,网络访问),那么就应该放到entity自身去。
有外部依赖的代码放到service之中。
这个是不是你的原意呢?

但是这样的归纳是从结果出发的,因为框架和我的设计需要我这样,所以就这样。如果从value出发呢?把逻辑放到domain中的价值是什么?放到service中的价值是什么?


所谓的无状态的逻辑,我所理解的就是与entity自身的状态有关,而与外部依赖无关的逻辑。这个外部依赖的范畴应该说比较广泛,包含数据库连接,网络访问,甚至是缓存读取,有其他依赖的工具类调用等等。

把部分逻辑放到Domain Object中的价值我已经说得很清楚了,只是为了代码的可维护性,可读性和可扩展性。这个不是最大的value嘛?我不理解你所说的从结果出发和从value出发的具体含义,请具体说明。或者说,你认为这些不能称之为价值,那么也请使用代码来说明,你比较关心什么价值?

另外我非常容易Robbin的观点。我们讨论领域模型,是必须要在某个特定的技术环境下。目前使用Java,使用Spring,似乎我还看不到不使用Domain Object + Service的理由。至于说到RoR,那就是另外的技术层面了。既然环境不同,技术背景不同,讨论相同的东西意义就不是很大了。
0 请登录后投票
   发表时间:2008-11-27  
今天才看Martin Flower的关于贫血领域模型的文章:http://www.martinfowler.com/bliki/AnemicDomainModel.html,发现我和Martin Flower的观点是如此接近,这也证明了我对DDD的理解是正确的。摘录几段吧

这段是谈贫血模型的缺点
引用
In essence the problem with anemic domain models is that they incur all of the costs of a domain model, without yielding any of the benefits. The primary cost is the awkwardness of mapping to a database, which typically results in a whole layer of O/R mapping. This is worthwhile iff you use the powerful OO techniques to organize complex logic. By pulling all the behavior out into services, however, you essentially end up with Transaction Scripts, and thus lose the advantages that the domain model can bring.


这段谈段到底应该将业务逻辑放在什么地方
引用
The key point here is that the Service Layer is thin - all the key logic lies in the domain layer. He reiterates this point in his service pattern:

    Now, the more common mistake is to give up too easily on fitting the behavior into an appropriate object, gradually slipping toward procedural programming.


0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics