贫血领域模型和事务脚本的区别

请问下,贫血的领域模型和事务脚本有何区别?贫血的领域模型,实体几乎没有了业务逻辑,那么业务逻辑能放在哪里?只能是服务中,那么这和事务脚本有何区别呢,思考好久,木有想出来答案说服自己,求指教。(是贫血的领域模型和事务脚本的区别,不是一般意义的领域模型----一般意义上的领域模型个人感觉是充血的)。谢谢。

2015-01-13 20:15 "@jdonTao"的内容
业务逻辑能放在哪里?只能是服务中,那么这和事务脚本有何区别呢 ...

业务逻辑放在服务中,服务变成了事务脚本,一般在服务中使用JTA或JDBC数据库锁或2PC两段事务保证业务逻辑的事务性。

贫血的领域模型是个状态模型,它上面的方法只是用来确保模型实例级别的状态合法性的。一个在模型实例级别合法的模型实例不一定在我们的系统中是合法的,比如它的标识与别人重复了它就在该类型的模型实例集合中不合法。
状态模型无法修改只能替换。在数据库中记录看似是可以修改的,其实都是在替换,是局部替换那些变更字段。
贫血的状态模型中的用来确保模型实例级别状态合法性的逻辑我觉得也属于领域逻辑。领域逻辑是和我们的系统一样分层管理的,领域服务中的是是领域逻辑,Actor中的是领域逻辑……甚至展示层逻辑中验证输入合法性的逻辑也是领域逻辑,当然在内层的服务层和贫血模型层也有重复的验证,系统将某些逻辑从内层投影到外层去执行只是为了减少对内层的无效请求和提高对用户的响应速度。
[该贴被anycmd于2015-01-14 11:38修改过]

2015-01-14 10:19 "@banq"的内容
服务变成了事务脚本 ...

这句话该如何理解?是否可以认为表现上相似,然而对于事物脚本来说,它没有分层的概念。而贫血领域模型也是领域模型的一种(书上称其为领域模型的反模式),因此具有分层的概念思想,也会有仓储,工厂,等一系列的存在。

2015-01-14 11:32 "@anycmd"的内容
它上面的方法只是用来确保模型实例级别的状态合法性的 ...
这些方法指的是?
认真看了几遍,,还是没有理解你的意思。惭愧。

2015-01-14 14:04 "@jdonTao"的内容
是否可以认为表现上相似,然而对于事物脚本来说 ...

简单地说:业务逻辑放在服务中,服务就是事务脚本。

业务逻辑放在MVC控制器中,控制器就是事务脚本。

原定义:Organizes business logic by procedures where each procedure handles a single request from the presentation.

2015-01-14 14:06 "@jdonTao"的内容
这些方法指的是? ...

这些方法指的是贫血的领域模型的构造函数和属性的get访问器,(如果贫血的领域模型是可变的还包括set访问器),除了这些方法外贫血的领域模型中就没有别的方法了。
我是这样考虑的:如果一个模型中既有丰富的行为又想要稳定的状态的话这是矛盾的,因为这个模型的行为一旦被调用往往就会改变模型的状态,非常类似波粒二象性。而波粒二象性最近被证明跟测不准原理是一回事,就是说如果没有把握住充血的原则的话容易导致我们的系统测不准。为了防止充血的领域模型上那些丰富的方法被不被期望的层和开发人员调用,为了能够测准我们的系统我们不得不去在为外层制造ViewModel、Dto这种对象来隐藏充血模型上丰富的行为,而这些ViewModel、Dto也是贫血的。

2015-01-19 10:22 "@anycmd"的内容
为了防止充血的领域模型上那些丰富的方法被不被期望的层和开发人员调用,为了能够测准我们的系统我们不得不去在为外层制造ViewModel、Dto这种对象来隐藏充血模型上丰富的行为,而这些ViewModel、Dto也是贫血的。 ...

同意。但是此处的ViewModel和Dto从实现上来说是贫血的,但上面这些理由已经足够说服它有存在的必要(现实中也如此)。依这个构造出来的领域部分仍然是充血的领域模型(因为领域对象是富行为的),没有服务层的存在或者服务层很薄。我倒觉得ViewModel和Dto属于应用服务层的一部分。这个和贫血的领域模型我觉得不同。

如果我把所有数据相关的东西都 json 化呢,这样数据部分只是一个 map,举例
class Admin {
Map json;
}
class User {
Map json;
}
数据部分完成了。现在我们赋予管理员的一个行为:给用户加分(包括负分)
class Admin {
Map json;
void scoreUser(User user, int score) {
if(checkRole(user))
user.json.score+=score;
else
throw new BusinessException("没有权限操作当前用户");
}
private boolean checkRole(User user) {
// 隶属于管理员能管理的组,才能操作这个用户
return admin.groups.contains(user.group);
}
}
我认为这个行为就是一种有血模式,到这里管理员已经完成了加分操作,后续的将 user 的新状态持久到 db 由另一个服务完成。如果是失血模式,会在某个 Server 中操作:
class XXXServer {
void scoreUser(User user, int score) {
// find user
// find admin
// check role
user.json.score+=score;
// save user
}
}
[该贴被freebox于2015-02-11 08:54修改过]