前面我们花了14篇的文章来给大家介绍经典DDD的概念、架构和实践。这篇文章我们来做一个完整的总结,另外生成一个Api接口文档。

一.DDD解决传统的开发的几大问题:

  1. 没有描述需求的设计模型;而是直接通过数据库表的方式体现,也就是需求与设计是脱节的。
  2. 编码的架构也没有与设计和需求对应起来。
  3. 业务逻辑与技术混在一起;业务逻辑可能直接调用的数据访问,这样把业务逻辑与数据访问的技术混在一起。
  4. 开发没有层次感和节奏感;系统没有一个统一的约束,开发人员没有一个统一的节奏,这主要体现在随意的编码。
  5. Bug 定位困难:当系统出现业务异常行为时,无法快速准确的定位出现问题的位置,因为系统不同开发人员的代码放置随意性。
  6. 需求变更响应缓慢:在大型的系统或产品中,当需要增加功能或修改现有功能时,因为代码架构的随意性,可能会出现改了功能可能会影响到其他的功能,造成系统极不稳定。

解决软件设计与开发问题的套路就是领域驱动设计(简称 DDD)。DDD 这个套路能够灵活解决以上的问题,为我们提供一个好的设计、架构以及高质量的代码。

二.DDD解决之道:

DDD 方法首先是需要将需求分析后,形成一个反应需求的领域模型。领域模型就是大家平常理解的类、类的属性、类之间的关系等。当然在 DDD 中,为了更好的将领域模型反应需求,对类、类的属性、类之间的关系等有一些模式的指导。比如类的属性可能是一般属性,也可能是值对象;比如有关系的类之间是否是代表一个整体概念、有相同生命周期、需要统一持久化等。所以我们的领域模型除了能够跑通需求外,还要考虑聚合根、实体、值对象、聚合等概念的应用,这样领域模型的设计才能更好的反应需求,也能够更好的将设计对应成有约束力的代码。另外 DDD 也提供了大量模式,告诉我们应该如何编写对应设计的代码,能够将我们的代码真正映射到设计;如何进行业务逻辑与持久化机制的剥离;如何进行更好的架构设计等。

1.DDD能应对复杂性:系统复杂性主要体现在三个方面。一是技术维度,有业务代码的实现、有与数据库或其他持久化存储交互的实现、有消息队列的实现、有身份验证与授权的实现、有 WebAPI 暴露的实现等;二是业务维度,有太多的模块和功能需要去做;三是时间维度,需要快速的开发,快速的响应需求的变更,快速的修正 Bug。DDD应对复杂性主要通过三个方面:

  • a. 技术维度:通过合理的架构分层,能够让每层关注自己的事情,比如领域层只关注业务逻辑的事情,仓储实现层只关注持久化数据与查询的事情,应用服务层只关注协调领域层与仓储实现层完成用例的事情,接口层只关注暴露给前端的事情。
  • b. 业务维度:通过将大系统划分成多个界限上下文,可以让不同团队和不同人只关注当前上下文的开发。在当前界限上下文中的领域层、仓储实现层、应用服务层、接口层都与其他界限上下文独立开来,这样可以专注开发,并且在修改代码与发布产品时,影响面较小。
  • c. 时间维度:通过敏捷式迭代快速验证,快速修正。

2.高效掌握DDD:

          a. 熟悉概念:充分熟悉前面文章介绍的界限上下文、实体、值对象、领域服务、聚合、聚合根、仓储、应用服务、接口等。

          b. 熟悉架构:充分熟悉前面文章介绍的经典DDD的架构。

c. 实践:前面文章从产品、经销商、订单三个界限上下文分析了需求、建立了领域模型、通过经典DDD架构实现了代码,需要你在实际项目中灵活的运用。

三.接口文档的生成

当我们已经做好了所有的接口后,需要生成WebApi在线的接口文档,便于前端人员进行查看与使用。.net core webapi中使用Swagger生成接口文档。

1.在WebApi项目中引入Nuget包:Swashbuckle.AspNetCore。

2.在WebApi项目属性的生成中,勾选“XML 文档文件”。此目的是可以包括WebApi中每个接口的注释。

3.在WebApi Startup.cs文件的ConfigureServices方法中,添加如下的代码:

 //swagger接口文档的信息
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info
{
Version = "v1",
Title = "产品界限上下文接口文档",
Description = "包括产品界限上下文所有接口的描述",
Contact =new Contact {Name="曹剑",Email="malaoko@hotmail.com"}
});
//使用Xml文档中接口的注释
var basePath = ApplicationEnvironment.ApplicationBasePath;
var xmlPath = Path.Combine(basePath, "Product.WebApi.xml");
c.IncludeXmlComments(xmlPath);
});

4.在Configure方法中,添加如下的代码:

 //制定swagger接口文档的访问url路径信息
app.UseSwagger();
app.UseSwaggerUI(p =>
{
p.SwaggerEndpoint("/swagger/v1/swagger.json", "Product接口");
});

5.修改Properties下的launchSettings.json文件中的两个launchUrl的值都改为swagger,这样在打开这个WebApi时,自动跳转到swagger帮助文件:

"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"Product.WebApi": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:5000"
}
}

6.访问时,最终的效果如下图:

7.在点击每个接口时,可以看到详细的调用说明:

本系列的文章就到这里,这个系列的文章主要是讲解了经典DDD,关于CQRS DDD与微服务,可以继续关注我们后续的系列文章,也可以加入QQ群或关注我们的

微信公众号。在后续CQRS与微服务的内容中,我们将实现如下的架构

微服务架构:

CQRS架构:

QQ讨论群:309287205

DDD实战进阶视频请关注微信公众号:

DDD实战进阶第一波(十五):开发一般业务的大健康行业直销系统(总结篇)的更多相关文章

  1. DDD实战进阶第一波(十):开发一般业务的大健康行业直销系统(实现经销商登录仓储与逻辑)

    上一篇文章主要讲了经销商注册的仓储和领域逻辑的实现,我们先把应用服务协调完成经销商注册这部分暂停一下,后面文章统一讲. 这篇文章主要讲讲经销商登录的仓储和相关逻辑的实现. 在现代应用程序前后端分离的实 ...

  2. DDD实战进阶第一波(一):开发一般业务的大健康行业直销系统(概述)

    本系列文章 DDD实战进阶第一波(一):开发一般业务的大健康行业直销系统(概述) DDD实战进阶第一波(二):开发一般业务的大健康行业直销系统(搭建支持DDD的轻量级框架一) 近年来,关于如何开发基于 ...

  3. DDD实战进阶第一波(二):开发一般业务的大健康行业直销系统(搭建支持DDD的轻量级框架一)

    要实现软件设计.软件开发在一个统一的思想.统一的节奏下进行,就应该有一个轻量级的框架对开发过程与代码编写做一定的约束. 虽然DDD是一个软件开发的方法,而不是具体的技术或框架,但拥有一个轻量级的框架仍 ...

  4. DDD实战进阶第一波(八):开发一般业务的大健康行业直销系统(业务逻辑条件判断最佳实践)

    这篇文章其实是大健康行业直销系统的番外篇,主要给大家讲讲如何在领域逻辑中,有效的处理业务逻辑条件判断的最佳实践问题. 大家都知道,聚合根.实体和值对象这些领域对象都自身处理自己的业务逻辑.在业务处理过 ...

  5. DDD实战进阶第一波(三):开发一般业务的大健康行业直销系统(搭建支持DDD的轻量级框架二)

    了解了DDD的好处与基本的核心组件后,我们先不急着进入支持DDD思想的轻量级框架开发,也不急于直销系统需求分析和具体代码实现,我们还少一块, 那就是经典DDD的架构,只有了解了经典DDD的架构,你才能 ...

  6. DDD实战进阶第一波(六):开发一般业务的大健康行业直销系统(实现产品上下文仓储与应用服务层)

    前一篇文章我们完成了产品上下文的领域层,我们已经有了关于产品方面的简单领域逻辑,我们接着来实现产品上下文关于仓储持久化与应用层的用例如何来协调 领域逻辑与仓储持久化. 首先大家需要明确的是,产品上下文 ...

  7. DDD实战进阶第一波(九):开发一般业务的大健康行业直销系统(实现经销商上下文仓储与领域逻辑)

    上篇文章主要讲述了经销商上下文的需求与POCO对象,这篇文章主要讲述该界限上下文的仓储与领域逻辑的实现. 关于界限上下文与EF Core数据访问上下文参考产品上下文相应的实现,这里不再累述. 因为在经 ...

  8. DDD实战进阶第一波(十一):开发一般业务的大健康行业直销系统(实现经销商代注册用例与登录令牌分发)

    前两篇文章主要实现了经销商代注册的仓储与领域逻辑.经销商登录的仓储与相关逻辑,这篇文章主要讲述经销商代注册的用例与经销商登录的查询功能. 一.经销商代注册用例 在经销商代注册用例中,我们需要传递经销商 ...

  9. DDD实战进阶第一波(十三):开发一般业务的大健康行业直销系统(订单上下文领域逻辑)

    前一篇文章主要讲了订单上下文的POCO模型,其中订单与订单项中有大量的值对象.这篇文章主要讲讲这些值对象以及订单项.订单相关的领域逻辑. 1.ProductSKUs值对象领域逻辑:ProductSKU ...

  10. DDD实战进阶第一波(四):开发一般业务的大健康行业直销系统(搭建支持DDD的轻量级框架三)

    上一篇文章我们讲了经典DDD架构对比传统三层架构的优势,以及经典DDD架构每一层的职责后,本篇文章将介绍基础结构层中支持DDD的轻量级框架的主要代码. 这里需要说明的是,DDD轻量级框架能够体现DDD ...

随机推荐

  1. H5唤醒app,第三方开源库

    在微信浏览器内,安卓打开应用宝,ios跳进appstore,基本都可以成功在外部浏览器内,已安装可进入应用内,未安装进入应用宝提示下载,需客户端支持.<!DOCTYPE html> < ...

  2. python基础其他

    目录: 一.Python为什么受欢迎的本质,知道的人寥寥无几? 二.PyCharm的模板设置 三.pycharm的一些快捷键 四.PyCharm最新2018激活 五.python虚拟环境--virtu ...

  3. C#实现 单点登录(SSO)

    SSO的基本概念 SSO英文全称Single Sign On(单点登录).SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统.它包括可以将这次主要的登录映射到其他应用中用于同 ...

  4. 动态规划——Best Time to Buy and Sell Stock IV

    这是这个系列题目的第四个,题目大意和之前的差不多,但是这次提供最多k次的操作,操作还是不能同时操作即必须结束前一个操作才能进行后一个操作. 状态比较好理解,就是题目要求的缩小版,dp[k][i]表示进 ...

  5. Linux下mysql开机自启动

    1,cd /etc/init.d/ 2,chmod +x mysql 3,chkconfig add mysql 4,chkconfig --list             显示服务列表 如果看到m ...

  6. Android EventBus技能点梳理

    EventBus为Github上的开源项目,地址:https://github.com/greenrobot/EventBus 疑问:1. 现在都是Android Studio创建的项目,如何导入这些 ...

  7. 数据分析——pandas

    简介 import pandas as pd # 在数据挖掘前一个数据分析.筛选.清理的多功能工具 ''' pandas 可以读入excel.csv等文件:可以创建Series序列,DataFrame ...

  8. 编程菜鸟的日记-初学尝试编程-C++ Primer Plus 第6章编程练习9

    #include <iostream> #include <fstream> #include <cstdlib> #include <string> ...

  9. C\C++ 内存对齐现象

    前几天一个在自学C语言的小伙伴问了我个问题,C语言结构体储存所占空间为啥和自己预测的不一样.看一下下面这一段代码: struct node{ int num; char ch; }a; printf( ...

  10. 学习之路-->大小文件读取并分页展示

    1.读取小文件,并进行分页 商品|价格 飞机|1000 大炮|2000 迫击炮|1000 手枪|123 ..... lis = [] n = 10 #每页显示10条信息 with open('小文件' ...