【DDD2】领域驱动设计精要

【DDD】领域驱动设计精要

目录

【DDD】领域驱动设计精要

1. 定义

2. 核心

3. 概念

4. 图解

分层图

模式图

5. 思考


扫描二维码关注公众号,回复: 5337395 查看本文章

正文

本文算是《领域驱动设计》这本书的读书笔记,加上自己的一些读后感。网上有很多这本书的读书笔记,但是都是别人的,不如自己总结的理解深刻。建议大家在读这本书时结合《实现领域驱动设计》一起看,同时,一定要去实际建模和编码,理论联系实际才能得其精髓。

本文是【DDD】系列文章的第一篇,可参考:使用领域驱动设计思想实现业务系统

1. 定义

DDD是Domain driven design(领域驱动设计)的简称,是一种软件设计和开发的方法论,特别适用于复杂业务领域软件设计和开发。可参考wiki: Domain-driven_design

2. 核心

  1. 将所有业务逻辑内聚到业务领域(domain)层,将设计和开发的关注点聚焦到业务领域;
  2. 建立通用的‘业务领域语言(Ubiquitous Language)’,Ubiquitous Language是工程师和业务领域专家(可以是产品经理、运营、业务相关人员)的桥梁;
  3. 战略上,通‘上下文(Bounded Context)’解耦各个业务系统/组件,通过‘防腐层(Anticorruption layer)’确保自有业务领域不受外界污染,通过‘开放主机服务(Open Host Service)’向外界公开服务;
  4. 战术上,将业务对象建模为entity和value object,entity有唯一业务标识且在其生命周期中状态可变,value object与之相反;关联性强的entity和value object聚合成一个Aggregate,每个Aggregate有一个root entity,确保Aggregate内容业务规则和行为的一致性;业务行为尽量建模在entity/ value object 上,当业务行为无法建模到任何业务entity/value object时,可以使用领域服务(domain service),使用factory创建复杂的业务entity,使用repository实现实体的重建和持久化操作;领域相关的通知等可以通过domain event发布出去。

3. 概念

  • Bounded context:边界上下文

划分领域边界,边界内领域模型保持一致,强调内聚,并与边界外的领域模型解耦。

  • Entity:领域实体

有唯一标识,可变的业务实体对象,它有着自己的生命周期。比如User、帖子等。

  • Value Object:领域值对象

没有唯一业务标识,通常依附于其他领域实体,值对象的内容不可变,要么被整体替换。如:用户点赞行为等。

  • Aggregate:聚合

是一组业务关联度很强的实体/值对象集合,每个聚合都有一个根实体(Root Entity),通过根实体可以路由到整个聚合。

  • Domain Event:领域事件

领域中发生的异步处理事件、异步消息通知等,比如:异步写入的登录历史记录。通常借助消息队列实现。

  • Domain Service:领域服务

当某些业务行为无法归类到某一个Entity/Value Object时,我们便可以创建领域服务来完成。比如:账户转账场景,涉及到两个不同的Account实体,再比如社区的敏感词过滤场景,帖子可以用,评论亦可以用,因此可以抽离到ContentFilter中完成。

  • Repository:仓库

严格意义上将仓库是基础设施层的东西,但是为了保持领域模型的整体性,我们将仓库的接口定义放到领域中,这样可以在领域中约束实体/值对象的增删改查接口,同时还可以方便地完成仓库的内存形式实现,使得领域模型弱依赖于持久化层。这一点在书中被成为‘依赖倒置’(参考《实现领域驱动设计》P372)。

  • Factory:领域对象工厂

用于复杂领域对象的创建/重建。重建是指通过respostory加载持久化对象后,重建领域对象。

4. 图解

分层图

User Interface —— 用户界面层。提供与用户/调用者交互的接口,可以是View,也可以是Restful api,还可以是二进制形式的tcp协议接口等。

Application —— 应用服务层。组合domain和infrastructure,完成具体的业务逻辑。

Domain —— 业务领域层。是ddd中的核心层,内聚所有的业务逻辑,保持领域的一致性。通常他可能会用到infrastructure层的公共组件。

Infrastructure —— 基础设施层。提供公共服务组件,比如validation、登录态校验、trace日志记录等等。

模式图

这张图囊括了DDD中的所有核心概念,上面部分是战术相关,下面部分是战略相关。不再赘述,建议读者直接查阅DDD原书,有详细介绍。值得反复细读。

5. 思考

  • DDD vs MVC 异同之处?
  • DDD vs CRUD 的区别是什么? 可参考:http://jlhood.com/there-is-no-u-in-crud/
  • DDD 能带来什么好处?有什么不好的地方?
  • DDD 适用的场景?
  • 你为什么选择使用DDD?

DDD带来的好处:
业务逻辑内聚到业务领域层,可以更好的保证业务规则的一致性;
软件的可维护性和可扩展性增强,工程师可以聚焦在业务领域层,并致力于业务领域模型的迭代和维护,适应新业务的发展;
软件的可测试性增强,领域层代码不需要借助用户接口层的入口便可以独立测试业务逻辑,通过repository的哑实现可以摆脱对数据持久层的依赖;
软件工程师和业务领域专家(产品经理)使用同一种语言交流,沟通成本降低,提升效率;【这一点在现实中或多或少在使用,但是比较模糊,很多时候大家会用到‘领域’这个词语,但是并不会刻意地坐下来讨论各自领域应当包含哪些实体......这也是大家可以进步的地方。】
业务领域层代码可以独立出来,共享到其他地方,可以轻松将服务产品化,云化;【这一点是yy出来的,可忽略。】
DDD不好的地方:
对工程师有较高的业务建模技能要求,期望他们能从复杂的业务上下文中识别出正确的业务模型,并将各个业务行为归入合适的entity/value object/domain service中;
项目前期需要投入更多的时间进行业务建模,不能快速进入开发阶段;
需要资深的业务领域专家参与进来,否则业务模型的频繁重构(重大改动)会带来额外成本;
DDD适用场景
业务逻辑复杂的系统;不太复杂的业务系统没有必要使用DDD,比如内容管理系统,只是对内容进行简单的增删改查;再比如渠道接入层系统,只是做请求的转发和翻译,没有核心业务逻辑,就没有必要使用DDD。
有资深的业务领域专家支持,需要有一个很懂业务的人,在业务上提供指导性的意见;
工程师都认可DDD设计思路,并积极主动地探讨和迭代,将业务模型日趋完善;
项目工期压力可以接受。
你为什么选择使用DDD
因为可以使用到DDD提供的好处,并且可以克服其带来的不变~

猜你喜欢

转载自blog.csdn.net/zhuiqiuuuu/article/details/87937725