领域驱动设计(Domain-Driven Design,DDD)入门简介

前置知识——领域模型

  1. 领域模型是对领域内概念类或现实世界中对象的可视化表示,也称为概念模型。
  2. 领域模型中的领域类通常只有属性,没有或很少的操作。
  3. 领域模型是对真实世界中概念类的表示,而不是软件对象的表示。

        领域模型是对现实世界里某个领域知识的抽象,是直接从客观世界抽离出来的概念。领域模型说起来就是两步走:找到概念类+建立关联,DDD强调的是先抽象出领域模型,再根据领域模型编写对应的逻辑代码。

        领域模型更接近于面向对象思想中的对象概念,模型中主要包括的是领域的业务属性和业务逻辑。业务属性和数据源无关,领域模型通过数据源代理层(Repository)对接数据。软件内实现的功能不直接调用领域模型的业务逻辑,而是通过应用层(Application)编排调用领域层(Domain)中所需要的领域服务来完成。

        领域模型与数据模型有很多共同点,设计过程中容易趋同,正确做法是将这两者有意识的分开。领域模型关注的是领域知识,是业务领域的核心实体,体现了问题域里面的关键概念,以及概念之间的联系。领域模型建模的关键是看模型能否显性化、清晰的表达业务语义,扩展性是其次。

        数据模型关注的是数据存储,所有的业务都离不开数据,都离不开对数据的CRUD,数据模型建模的决策因素主要是扩展性、性能等非功能属性,无需过分考虑业务语义的表征能力。

        Robert在《整洁架构》里面的观点,领域模型是核心,数据模型是技术细节。然而现实情况是,二者都很重要。DDD 提倡从领域模型设计出发,而不是先设计数据模型。

从MVC到DDD

        MVC模式由模型(Model)、视图(View)和控制器(Controller)组成。MVC是三层架构,“三层”是指表示层(USL,User Show Layer)、业务逻辑层(BLL,Business Logic Layer)、数据访问层(DAL,Data Access Layer),分别对应V、C、M。MVC架构是一种贫血模型,数据与业务分离。随着软件版本的不断开发业务越来越复杂,负责业务逻辑的Service层越来越臃肿,实体类间的关系也变复杂,因此可维护性很差。

        领域驱动设计(DDD,Domain-Driven Design)为解决上述问题而生。DDD面向对象设计,把数据和行为绑定,是一种充血模型。DDD架构一般可分为四层,从上至下分别为接口层(Interface)、应用层(Application)、领域层(Domain)、基础层(Infrastructure)。

https://img-blog.csdnimg.cn/img_convert/d0ca912729d606987a5d275751cbb0ea.png

        四层架构其中最核心的部分为领域层,领域层最核心的内容则是聚合(Aggregate)。聚合的本质就是建立了一个比对象粒度更大的边界,聚集那些紧密关联的对象,形成了一个业务上的对象整体。使用聚合根(Aggregate Root,同样是一个实体)作为对外的交互入口,从而保证了多个互相关联的对象的一致性。

下面观察一个很典型的例子,假设问题领域是一个企业内部的办公用品采购系统:

  1. 企业的员工可以通过该系统提交一个采购请求,一个请求包含了若干数量、若干类型的办公用品(称为采购项)。
  2. 主管负责对采购申请进行审批。
  3. 审批通过后,系统会根据提供商不同,生成若干订单。

如果用传统的以数据库为中心的建模方式,首先会进行数据库设计,那么将会得到非常复杂的数据表,其中包含采购请求、采购项、订单等多个表;即使使用面向对象技术和ORM(对象-关系映射),把数据表等技术细节忽略后,虽然模型元素和复杂性相对减少,但业务规则在传统的面向对象方法中并没有严格的实现约束。

        在采购的过程中,采购请求和采购项在问题场景中不可分割,先前我们拆开了设计是为了编码。如果仅仅对采购这个问题进行分析,这两项就不应该分开,而是一个更大的整体。另外,采购请求与采购项之间的相互操作也将成为整体内的一部分,外界通过访问采购请求即可操作这个整体,无需理会整体内的运作。这个整体即是DDD中的聚合,采购请求即是外界访问这个聚合必须通过的聚合根,由于聚合是一个整体,业务一致性就得到了保证。

        聚合遵循高内聚,低耦合的原则,内部的对象应在问题域、生命周期、场景频率上保持一致性,是一个完整的概念。通过把对象组织为聚合,在基本的对象层次之上构造了一层新的封装。封装简化了概念,隐藏了细节,在外部需要关心的模型元素数量进一步减少,复杂性下降。在后续的迭代升级或维护过程中,开发者仅需重点关注对应的聚合内部,聚合外部的低耦合修改起来会相对轻松。

        与MVC中把所有业务逻辑放在Service层不同,DDD中可以把业务逻辑放在实体内、领域服务内、应用层内三个地方,如何对问题场景中的业务逻辑拆解分类放在合适的位置成为DDD设计中的难点。一般来讲,实体内的方法仅需调用实体内的属性,领域服务在聚合中与实体是同等级的部分,领域服务内的方法负责同个聚合内不同实体间的交互逻辑。至于应用层中的方法则是协调多个领域层的聚合,对领域服务进行编排调用完成其本身的功能,这些功能经过接口层的封装即可供用户使用。

https://img-blog.csdnimg.cn/img_convert/f63b80a343ca26d7858a53cbbf27ea64.png

        由于DDD与MVC相比做了更多的封装,因此毫无疑问是更加复杂的,定义的边界也将消耗更多的内存空间。对于业务逻辑并不复杂的场景,MVC的Service层不会过于冗杂,对比起设计难度较高的DDD会更加适用;而对于大型的、复杂的、 需要频繁迭代升级和维护的系统来讲,DDD将发挥出其独特的优势。

引用:深入理解领域驱动设计中的聚合 - 知乎 (zhihu.com)

           MVC和DDD的对比_ddd架构和mvc架构区别_狂奔的蜗牛Evan的博客-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值