领域Model?

简介:

前言

领域驱动设计里有很多东西,我们可以应用在各种各样的开发模式里,所以接下来说的一些东西,我们可以部分使用。

说道领域驱动的领域,大家肯定就要开始说Bounded Context,聚合,聚合根,容易让大家搞糊涂。 我觉得先抛开这些概念,后面再来说如何设计聚合,先简单来说。

模型

过去,我们在多层设计里定义了很多Model, 数据库的Model(DB Entity), 然后为了不依赖数据库,我们有设计了业务的Domain Model, 同时我们又设计了ViewModel, 这样一般也没什么问题,职责也很清晰。但是有几个问题

  1. 我们要做很多的模型转换,转入转出。当然我们可以用AutoMapper来但是AutoMapper的性能实在难以恭维,大家可以在网上搜索AutoMapper performance.
  2. 领域模型成了一个单纯的DTO了。

领域模型

首先我们要看领域,就是我们尽量把业务聚合到一个领域里,比如我们要做一个功能,可以看到用户每一次的登录日志,那个这个登录日志其实就是属于用户这个领域里。

其次我们看模型,原来我们的模型都是只有属性,也就是贫血模型,贫血的意思就是没有行为,像木乃伊一样,但是实际上领域是我们要完成业务的最主要的地方,我们希望领域能够自制,也就是领域自己管理自己。

示例

比如有一个Employee, 他的状态有Active, Pending, DeActive, 业务上是Pending只能改为Active.

1
2
3
4
5
6 7 8 9 10
    
    public class Employee : Entity { public Name Name { get; set; } public EmployeeStatus EmployeeStatus { get; set; } } 

如果是贫血的Employee模型,我们往往代码如下

	
	public class EmployeeService : IEmployeeService { private readonly IUnitOfWorkFactory _unitOfWorkFactory; private readonly IEmployeeRepository _employeeRepository; public EmployeeService(IUnitOfWorkFactory unitOfWorkFactory, IEmployeeRepository employeeRepository) { _unitOfWorkFactory = unitOfWorkFactory; _employeeRepository = employeeRepository; } public void ChangeStatus(EmployeeStatus status, Guid employeeId) { using (var unitOfWork = _unitOfWorkFactory.GetCurrentUnitOfWork()) { var employee = _employeeRepository.GetById(employeeId); employee.EmployeeStatus = status; unitOfWork.Commit(); } } } 

但是上面的代码的问题就是领域没有自治,本来修改我的状态是我的事,你能不能修改,外面随意修改我的状态是很危险的,比如Pending状态只能改为Active状态。 所以如果不是贫血的模型,我们代码就会这样,让领域自己来管理

	public class Employee : Entity { public UserId UserId { get; private set; } public EmployeeStatus EmployeeStatus { get; private set; } public void ChangeStatus(EmployeeStatus status) { if (this.EmployeeStatus == EmployeeStatus.Pending && status != EmployeeStatus.Active) { throw new Exception("Only can Active when status is pending"); } this.EmployeeStatus = status; } } public class EmployeeService : IEmployeeService { private readonly IUnitOfWorkFactory _unitOfWorkFactory; private readonly IEmployeeRepository _employeeRepository; public EmployeeService(IUnitOfWorkFactory unitOfWorkFactory, IEmployeeRepository employeeRepository) { _unitOfWorkFactory = unitOfWorkFactory; _employeeRepository = employeeRepository; } public void ChangeStatus(EmployeeStatus status, Guid employeeId) { using (var unitOfWork = _unitOfWorkFactory.GetCurrentUnitOfWork()) { var employee = _employeeRepository.GetById(employeeId); employee.ChangeStatus(status); unitOfWork.Commit(); } } } 

因此可以看出,我们把业务代码尽量写在领域里让领域自治。

后记

其实领域驱动设计最难的就是设计领域(Domain), 也就是后面会说到的AggregateRoot 聚合,但是我想我们先让领域不再贫血,这样在传统的多层设计,数据驱动等架构都可以使用这种模式。

 

 

分类: 其它, 软件设计
 
 
本文转自左正博客园博客,原文链接: http://www.cnblogs.com/soundcode/p/7161966.html /,如需转载请自行联系原作者
相关文章
|
1月前
组件v-model
组件v-model
19 0
|
2月前
|
JSON 前端开发 开发者
sap.ui.model.Model.checkUpdate 方法介绍
sap.ui.model.Model.checkUpdate 方法介绍
12 0
|
23天前
|
机器学习/深度学习 TensorFlow API
Keras 的模型(Model)和层(Layers)的介绍
Keras 的模型(Model)和层(Layers)的介绍
17 1
|
1月前
|
JavaScript 编译器
组件 v-model
组件 v-model
|
4月前
|
JavaScript
v-model和:model的区别
v-model和:model的区别
36 0
|
5月前
|
机器学习/深度学习 自然语言处理 PyTorch
Model Inference
模型推理(Model Inference)是指使用已经训练好的机器学习模型来对新数据进行预测或分类的过程。模型推理是机器学习中的一个重要环节,其目的是利用训练好的模型对新数据进行预测或分类,从而得到结果。
82 1
|
9月前
|
机器学习/深度学习 并行计算 PyTorch
【PyTorch】Training Model
【PyTorch】Training Model
64 0
|
存储 测试技术
测试模型时,为什么要with torch.no_grad(),为什么要model.eval(),如何使用with torch.no_grad(),model.eval(),同时使用还是只用其中之一
在测试模型时,我们通常使用with torch.no_grad()和model.eval()这两个方法来确保模型在评估过程中的正确性和效率。
605 0