领域驱动设计(DDD:Domain-Driven Design)

DDD最大的好处是:接触到需求第一步就是考虑领域模型,而不是将其切割成数据和行为,然后数据用数据库实现,行为使用服务实现,最后造成需求的首肢分离。DDD让你首先考虑的是业务语言,而不是数据。重点不同导致编程世界观不同。

上面的话摘自:jdon对DDD的解释:
原来是将数据和行为割裂,现在将他们放在一起,这就是面向对象的设计和分析的东西吧。

但是上面的话,并没有说,创建了业务模型,业就是领域模型之后,继续怎么办啊?
应用数据驱动的方法,大家都知道,在业务需要的脚本代码写在service中,DAO存储数据在数据库中。
DDD创建的业务模型,那相当于就是讲原来service中的代码,下移中实体中了吧!
那这样在领域模型中,就有了用于实体本身CRUD的方法,还有一些从service句中下移的代码。
数据存储还和原来一样


2013-12-19 09:49 "@
sinaID30957"的内容
那这样在领域模型中,就有了用于实体本身CRUD的方法,还有一些从service句中下移的代码 ...

这时的新Service服务如同一个broker,也就是商人,做倒进倒出生意,把工厂(领域)的产品卖给客户。

至于CRUD放入数据存储中,也就是Respository中,CRUD本来就是数据存储的概念,不是业务领域概念,这个前提是你的系统复杂,不是简单得只有CRUD,那么DDD不适用。

DDD是在CRUD基础上有复杂业务逻辑,SOA解决了CRUD基础上的流程逻辑,但是并没有解决领域逻辑,聚合以及聚合的状态变化,聚合状态是因为受到外部流程变动而变化,但是聚合状态不是全局变量,不是流程想改就改,得通过领域规则这一关。

打个比喻,居委会要举行选举,选举有选举的流程,其中一个步骤是通知你参加,但是你可以不参加,不能因为外部流程,你没有自己的领域规则。

不是将业务代码下移到了实体中,是下移到了领域对象中。

实体就是ORM中映射数据表的类而已,并不需要方法和业务逻辑。

领域对象也没有CRUD方法,领域对象只能改变状态,改变领域对象的状态才出发了实体的CRUD方法。

不要被表象迷惑。
DDD不是简单的将方法下沉到领域对象中;
搞DDD,首先要搞清楚的是OOAD的原则。其中最重要的关键点就是职责如何分配。

所以,不是因为用了DDD所以方法才要下沉到领域对象中,而是因为正视了OOAD的基本原则才将有些方法下沉到领域对象中。

方法、职责放service还是放领域对象中,不是DDD规定的,而是面向对象的基本原则就已经明确定义了的。看一下Craig Larman写的GRASP九大OO原则,再学DDD,就觉得非常简单了。

“领域对象也没有CRUD方法,领域对象只能改变状态,改变领域对象的状态才出发了实体的CRUD方法。”

那领域对象到底有什么组成?

比如一个订单有产品信息,有收货地址,有供应商信息,订单被NEW出来之后就真实的存在了。你可以将订单的状态改变为无效,等待收货等等。但是你无法物理的删除这个订单,因为订单并不需要知道自己是否被持久化了。

将订单持久化是持久层干的活,持久层的策略可以将三个月以前的无效订单移动到“历史订单”表。不论持久层将数据存储到哪个表,NOSQL还是内存缓冲区,都不影响订单这个对象的业务规则。

换句话说,领域对象只需处理业务逻辑,无需将自身持久化。

因为持久层有自己的策略,以最优化的结构存储数据,我本人常用的策略有以下几种:
1。批量提交:一般是增加点击量之类不重要的业务,待积累了一定的数量之后一次性提交
2。预查询:系统定期执行配置文件中的查询操作,将结果存储到NOSQL缓存中。
3。查询缓存:缓存查询操作,如果缓存被二次命中,则延长缓存时间。
4。自动分表:定义分表规则,将大量的数据分散到不同数据中存储。
5。写入缓存:将原本要写入中心数据库的数据写入本地的nosql,然后定期向中心数据库同步。


2013-12-19 11:51 "@
banq"的内容
打个比喻,居委会要举行选举,选举有选举的流程,其中一个步骤是通知你参加,但是你可以不参加,不能因为外部流程,你没有自己的领域规则。 ...



// C代码
public class Order
{
//订单项
public OrderItem[] Items { get; }
//订单状态
public EnumOrderState OrderState { get; }
//“尝试改变订单状态”事件,供业务规则引擎注册响应
public event EventHandler<OrdrtStateChangeEventArgs> OrderStateChange;
//尝试改变订单状态,供服务层调用。能不能改变成功取决于业务规则,改变成功了怎样写入数据库取决于持久规则
public void ChangeOrderState(OrderState newOrderState)
{
OrderStateChange(this, new OrderStateChangeEventArgs
{
CurrentState = this.OrderState;
NewState = newOrderState;
});
}

[该贴被gameboyLV于2013-12-21 16:08修改过]