一、简介
DDD(领域驱动设计) 是一种处理高度复杂领域的设计思想,是一种架构设计方法论,是一种设计模式。以高内聚低耦合为目的,把一个复杂的软件应用系统中各个部分进行一个很好的拆解和封装,对软件系统进行模块化的一种思想。DDD不仅可以用于微服务设计,还可以很好地应用于企业中台的设计,也适用于传统的单体应用。
二、框架介绍
1、文字介绍
下面我手动创建了几个项目并标识每个项目的职责
如图:这是我创建的项目
ABP_vNext_Application => 领域应用接口实现层
ABP_vNext_Application_Contracts => 领域应用接口层
ABP_vNext_Domain => 领域层
ABP_vNext_Domain_Shared => 领域共享层
ABP_vNext_EFCore => 领域数据库访问层
ABP_vNext_HttpClient => 领域UI展现层(适用winform这种项目调用)
ABP_vNext_WebApi => 领域UI展现层(适用 前后端分离,前端通过 http url地址调用数据)
ABP_vNext_WebMvc => 领域UI展现层(适用前后端整体,MVC项目)
项目之间的依赖关系:如图
2、伪代码讲解
2.1、 ABP_vNext_Domain => 领域层
用来实现实体类
领域层7大概念: 如图
(1)实体:对应实体类cs文件
例如: 我有一个学生Student实体类,好友Friend实体类
(2)聚合根:对应数据库存储的表;聚合:对应数据根的外键关系;
聚合根: Student
聚合:每一个学生对应的 List<Friend>
(3)仓储: 对应聚合根的操作接口
/// <summary>
/// 仓储(只操作聚合根,不操作实体。)
/// 也就是说,只操作Student这个类,Friend这个类不操作
/// 学生相关接口
/// </summary>
public interface IStudentRepository
{
List<Student> Get();
bool Insert(Student student);
}
(4)领域服务: 对应主题业务不变的逻辑
/// <summary>
/// 学生领域服务
/// </summary>
public class StudentDomainService
{
/// <summary>
/// 属性依赖注入接口
/// </summary>
public IStudentRepository StudentRepository { get; set; }
/// <summary>
/// 创建学生
/// 需求:判断学号是否重复
/// </summary>
public void CreateStudent(Student student)
{
//查询数据库学生
List<Student> students = StudentRepository.Get();
if (students.Any(x=> x.Number == student.Number))
{//学号重复
return;
}
//添加学生到数据库
StudentRepository.Insert(student);
}
}
(5)值对象:对应实时变化的数据,不要存储到数据库一张表,存到对象身上一个json字符串即可
/// <summary>
/// 学生值对象类
/// </summary>
public class StudentImage
{
public string ImagerName { get; set; }
public string ImagerUrl { get; set; }
}
存储到学生表中 就为一个StudentImage组成的json字符串
(6)规约:对应会根据不同场景变化的业务逻辑
/// <summary>
/// 学生规约类
/// 用来写一个 业务逻辑判断
/// </summary>
public class StudentSpecification
{
/// <summary>
/// 添加学生
/// 需求1: 学号必须包含1234
/// </summary>
public bool CreateImageOnPC(Student student)
{
return student.Number.ToString().Contains("1234");
}
}
遇到不同场景创建不同的类写不同的逻辑即可
(7)领域事件:对用实施完增删改查操作后续会导致的事情
/// <summary>
/// 添加学生事件
/// 用来写一些 添加学生后 导致的后续反应
/// 例如: 通知前端刷新页面
/// </summary>
public class InsertEvent
{
}
2.2、ABP_vNext_Application_Contracts => 领域应用接口层
用来定义一些前端需要用到的Dto展示数据,已经前端调用的接口
/// <summary>
/// 添加学生对象数据传输DTO(用来和页面交互)
/// 例如: 创建学生 用户只需填写 学号\姓名 即可不用展示其他过多字段
/// 好处:
/// 1、保护领域实体
/// 2、适应用户页面需求变化
/// </summary>
public class InsertDto
{
public int Number { get; set; }
public string Name { get; set; }
}
/// <summary>
/// 学生领域应用服务接口层
/// </summary>
public interface IStudentAppService
{
/// <summary>
/// 前端调用的方法
/// 添加学生方法
/// </summary>
/// <param name="insertDto"></param>
public void InsertStudent(InsertDto insertDto);
}
2.3、ABP_vNext_Application => 领域应用接口实现层
用来实现领域应用接口层的接口
/// <summary>
/// 学生领域应用服务接口实现层
/// </summary>
public class StudentAppService: IStudentAppService
{
/// <summary>
/// 属性依赖注入接口
/// </summary>
public IStudentRepository StudentRepository { get; set; }
/// <summary>
/// 前端调用的方法
/// 添加学生方法
/// </summary>
/// <param name="insertDto"></param>
public void InsertStudent(InsertDto insertDto)
{
//先将Dto学生数据转化成正规数据库存储的student数据
Student student = new Student()
{
Id = 1,
Number = insertDto.Number,
Name = insertDto.Name
};
//添加学生到数据库
StudentRepository.Insert(student);
}
}
2.3、ABP_vNext_EFCore => 领域数据库访问层
用来对接数据库操作
/// <summary>
/// 仓储(接口)实现
/// </summary>
public class StudentRepository : IStudentRepository
{
public List<Student> Get()
{
//模仿数据库查询数据
return new List<Student>
{
new Student() { Id = 1, Name = "小王"} ,
new Student() { Id = 2, Name = "小小x"}
};
}
public bool Insert(Student student)
{
//模仿数据库新增数据
return true;
}
}
2.4、 ABP_vNext_Domain_Shared => 领域共享层
/// <summary>
/// 领域共享服务层,用来存储项目中一些常量
/// 学生常量类
/// </summary>
public class Student_Shared
{
//例如,在这存储一些学生登录的验证码
//key = 学生Id, value = 验证码
public static Dictionary<string, string> StudentCode = new Dictionary<string, string>();
}
三、快速搭建项目模板
在cmd命令窗口中输入: abp new 项目名称 -dbms MySQL --tiered -csf
以上就是初步了解的DDD领域设计模式,欢迎大家到评论区一起研究!!!