DDD领域模型和充血对象

DDD领域模型

官方说法

领域驱动设计,它是对面向对象的的分析和设计(OOAD,Object Orient Analysis Design)的一个补充,对技术框架进行了分层规划,同时对每个类进行了策略和类型划分。领域模型是领域驱动的核心 ,采用DDD的设计思想,业务逻辑不再集中在几个大型的类上,而是在大量相对小的领域对象上,这些类具有自己的状态和行为,每个类都是完成的独立的,并与现实领域的业务对象形成一种映射。基于DDD的架构设计,保证了系统的可维护性,扩展性和敏捷性,在处理复杂业务逻辑方面有着明显的优势!

以上是官方的说法:http://www.jdon.com/ddd.html

个人理解

传统的软件生产过程:分析,设计,编程,测试,部署。然而在真实的环境中,分析和设计时分开的,分析人员不需要了解设计,只需要知道设计-实现难度即可,而设计人员在接到分析的需求后,并不能很好的理解需求。而DDD就是抛弃了这种做法,在分析阶段,就将设计加入其中,给分析人员提出了更高的要求。

DDD的弊端也十分明显,如果需求出现大范围改动,整个模型可能不再适合,这个时候吗,需要重新设计模型。给后期的维护带来更大的麻烦。 这也是

DDD革命性在于:领域模型准确反映了业务语言,而传统的分层架构只关心数据, 这些数据对象除了简单读、写操作外,没有任何业务方法,被比喻成失血模型,那么领域模型这种带有业务方法的充血模型到底好在哪里?

看到领域模型代码,就看到业务需求,没有翻译没有转换,保证软件真正实现“拷贝不走样”。

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

DDD的特点

分层架构

成熟、清晰的分层架构。

领域对象与世界的业务映射。

明确的职责划分。

复用性

领域对象是核心

领域对象完美的描述了业务。

设计基于领域对象,而不是数据库。

适用对象

具备复杂的业务逻辑的如软件

对设计和开发人员要较高

不适用普通的CRUD操作

系统维护性和扩展性高

DDD 的分层

一般的系统设计是,一般分为三层:数据层,业务层,表现层,即MVC模式。

DDD分层的方式发生了变化分成了:表现层,应用层,领域层,基础层。

表现层也就是view层,这个无论怎么设计都不会丢。

应用层:用来协助应用活动,不包含业务逻辑,不保存对象,只保存任务状态,相当于一个任务流。

领域层:包含领域信息,包含绝大部分的业务,保留业务对象的状态,需要将业务对象交给持久化处理。

基础层:可以理解为持久化,

DDD中的几个核心对象

Entites:包含业务逻辑的实体(domain)

Factories:工厂类,用来生成对象

Respositories:持久化,本身就是DAO

Service:服务层,为Controller提供接口,负责领域对象的再次封装和业务流处理。

模型中的Model

在DDD模型中,一般分为三种模型,ViewModel,DomainModel,Model。

ViewModel与UI数据对应

DomainMode与领域业务模型对应,与业务关联。

Model实体模型,与数据表对应。

失血、贫血、充血、胀血模型

失血模型:只有getter/setter方法,没有任何业务逻辑,也不包含任何的实体关系。

优点:思路清晰,编写代码方便,所有业务都在service中。

缺点:service过重,业务中出现大概率重复调用的情况。

贫血模型:在这里Entity应该叫domain。简单来说,就是除了getter/setter方法外,兼任了组装实体的业务,并且保留实体之间的关系,或者说是实体之前的嵌套。依然是service–>DAO–>domain(entity)的层级关系。

优点:各层级单向依赖,结构清楚,很容易编写,也容易维护。稳定。

缺点:domain部分流转被封到了Service层,不够面向对象。Service也比较厚重。

充血对象:充血模型是将DAO也挪到domain中,由domain去持久化对象。调用关系变成了service–>domain–>DAO。

优点:很面向对象。Service很薄,

缺点:DAO和domain双向依赖,存在很多问题。划分domain和service业务混杂,不同人员有不同理解。Service也需要调用domain的业务方法,相当于又封装了业务。

胀血对象:取消Service层,只保留domain–>DAO。

优点:简化分层

缺点:业务暴露太多给Web层。service的业务也被强行加入了domain,可能引发domain不稳定。

四种模型中,失血和胀血模型,不应该被提倡,因为弊大于利。而贫血,充血这两种在技术上已经很成熟了。但是推荐使用贫血模型。因为充血模型中,DAO和domain双向依赖带来结构问题。而且在批量操作domain的结构,很不合理。推荐使用贫血模型,增加少量的业务在entity中。比如参数构造,getter/setter中加入少量的逻辑判断。编码优先级最高的是完成业务的同时,引起的BUG更少。至于是不是面向对象,BUG少就行了。

点赞