作业二

B9E83DA8 / 2023-05-19 / 原文

这个作业属于哪个课程 2022软件代码开发技术
这个作业要求在哪里 作业二
这个作业的目标 1.学习了解软件设计原则、设计模式

这是对博客领域驱动设计在爱奇艺打赏业务的实践的读书笔记,这篇博客主要介绍了领域驱动设计的具体应用方式。

内容概况

DDD

领域驱动设计(Domain-Driven Design,以下简称DDD)思潮的形成要追述到30几年前,17年前,Eirc Evans定义了领域驱动设计的概念。

使用领域驱动设计可以为业务开发带来以下优点:

  • 业务的效率有显著提升:
  • 新需求接入开发成本降低;
  • 更换底层中间件开发成本降低;
  • 项目熟悉成本降低(对DDD有基本了解为前提);
  • 单测开发成本指数级降低;
  • 上线风险、成本降低。

领域驱动设计不是一套全新的特殊架构,是任何项目代码经过重构,满足高可维护性、高可扩展性、高可测试性、代码结构清晰之后必将达到的终点。

DDD要求

领域驱动设计的核心要求有两个:

基于领域建模而非数据建模

进行项目设计时,我们应该从业务领域角度出发思考问题,而不应该从数据库角度。使用领域驱动设计对系统进行概要设计时,通常会通过领域、子域、限界上下文几个层次对系统进行设计。

  • 领域:从广义上讲,领域即是一个组织所做的事情以及其中包含的一切。每个公司或组织都有它自己的业务范围和做事方式,这个业务范围以及其在其中所进行的活动便是领域。当你为某个公司开发软件时,你面对的便是这个公司的领域。这个领域对于你来说应该是明确的,因为你在这个领域中工作。
  • 子域:对于领域模型包含“领域”这个词,我们可能会认为整个业务系统创建一个单一的、内聚的、功能全能式的模型。然后这并不是我们使用DDD的目标。正好相反,在DDD中,一个领域被分成若干小的域,这些若干的小的域即子域。事实上,在开发一个领域模型时,我们关注的通常只是这个业务系统的某个方面,对领域的拆分将有助于我们成功。
  • 限界上下文:一个由显示边界限定的特殊职责。领域模型存在于边界之内,在边界内,每一个模型概念,包括它的属性和操作,都具有特殊的含义。

满足六边形架构设计

2005年Alistair Cockburn提出了六边形架构,又被称为端口和适配器架构。观察上图我们发现,对于核心的应用程序和领域模型来说,其他的底层依赖或实现都可以抽象为输入和输出两类。组织关系变为了一个二维的内外关系,而不是上下结构。每个io与应用程序之前均有适配器完成隔离工作,每个最外围的边都是一个端口。基于六边形架构设计的系统是DDD追求的最终形态。

通过应用DDD的系统符合六边形架构,我们可以实现以下目标:

  • 独立于框架:架构不应该依赖某个外部的库或者框架,不应该被框架的结构所束缚;
  • 独立于UI:前台展示的样式可能会随时发生变化,但是底层架构不应该随之而变化;
  • 独立于底层数据源:软件架构不应该因为不同的底层数据存储而产生巨大改变;
  • 独立于外部依赖:无论外部依赖如何变更、升级,业务的核心逻辑不应随之而大幅变化。

问题补充

1、事务

一个事务内只操作一个聚合实例,如果发现一次事务内逻辑过多,可以考虑剥离出独立的聚合,采用最终一致性。基于这个基础,最适合声明事务的层是应用层。

2、查询

CQRS 在 DDD 中是一种常常被提及的模式,它的用途在于将领域模型与查询功能进行分离,让一些复杂的查询摆脱领域模型的限制,以更为简单的 DTO 形式展现查询结果。同时分离了不同的数据存储结构,让开发者按照查询的功能与要求更加自由的选择数据存储引擎,CQRS的具体实践可以自行查找资料。

3、框架无关

基于六边形架构设计,已经做到了与底层实现、框架、中间件无关。但还有一个最大的框架依赖spring,我们的做法是领域内使用的spring bean通过传参方式,实现领域层框架解耦。

4、成本

成本是我们实践DDD时需要考虑的一个很重要的问题,学习成本、改造成本、兼容成本等等都是需要特别关注的。在动手实践之前,建议优先评估好成本。

心得体会

在以往进行开发的过程中,我了解到对于软件开发来说应用一个良好的设计框架是十分重要的,一个良好的设计框架能够显著地提示软件的设计、开发和维护阶段的效率,可以使软件更加易于开发、可维护性更强。

在个人的软件开发经历中,比较常用到的一种软件架构是依赖倒置结构。在系统分层架构的一个重要原则是每层只能与位于其下方的层发生聚合。为了实现接口的定义与实现解耦,接口定义在领域层,实现定义在基础设施层。但这样违背了由顶至底的单项依赖原则。
为了解决这个问题,高层模块不应该依赖于低层模块,两者都应该依赖于抽象。抽象不应该依赖于细节,细节应该依赖于抽象。这样一来就实现了依赖倒置,一个依赖倒置的系统结构将如下如下:

基础设施层现在位于所有层的最上方,这样它可以实现所有其它层定义的接口。