qidao123.com技术社区-IT企服评测·应用市场

标题: 实现领域驱动设计 - 使用ABP框架 - 领域逻辑 & 应用逻辑 [打印本页]

作者: 丝    时间: 2022-8-9 14:43
标题: 实现领域驱动设计 - 使用ABP框架 - 领域逻辑 & 应用逻辑
领域逻辑 & 应用逻辑

如前所述,领域驱动设计中的业务逻辑分为两部分(层):领域逻辑和应用逻辑:

虽然定义很明确,但实现起来可能并不容易。您可能无法决定哪些代码应该位于应用程序层,哪些代码应该位于领域层。本节试图解释其中的差异
多个应用程序层

当系统比较大时,DDD有助于处理复杂性。特别是,如果在一个领域中开发了多个应用程序,那么领域逻辑与应用程序逻辑的分离就变得重要得多。
假设您正在构建一个具有多个应用程序的系统

每个应用程序都有不同的需求、不同的用例(应用服务方法)、不同的dto、不同的验证和授权规则……等
如果将所有这些逻辑混合到单个应用程序层会使您的服务包含太多的逻辑,使代码更难开发、维护和测试,并导致潜在的bug
如果一个领域有多个应用程序:
这样的设计使得区分领域逻辑和应用程序逻辑变得更加重要。
为了更清楚地了解实现,您可以为每个应用程序类型创建不同的项目(.csproj)。例如:
案例

本节包含一些应用程序服务和领域服务示例,以讨论如何决定将业务逻辑放置在这些服务中
示例:在领域服务中新建组织
  1. public class OrganizationManager : DomainService
  2. {
  3.     //省略了依赖注入
  4.     public async Task<Organization> CreateAsync(string name)
  5.     {
  6.         if(await _organizationRepository.AnyAsync(x => x.Name == name))
  7.         {
  8.             throw new BusinessException("IssueTracking:DuplicateOrganizationName");
  9.         }
  10.         await _authorizationService.CheckAsync("OrganizationCreationPermissin");
  11.         Logger.LogDebug($"Creating organization {name} by {_currentUser.UserName}");
  12.         var organization = new Organization();
  13.         await _emailSender.SendAsync(
  14.             "admin@issuetracking.com",
  15.             "New Organization",
  16.             "A new organization created with name: " + name
  17.         );
  18.         return organization;
  19.     }
  20. }
复制代码
让我们一步一步地看看 CreateAsync 方法,来讨论代码部分是否应该放在领域服务中
示例:在应用服务中新建组织
  1. public class OrganizationAppService : ApplicationService
  2. {
  3.     //省略了依赖注入
  4.     [UnitOfWork]
  5.     [Authorize("OrganizationCreationPermissin")]
  6.     public async Task<Organization> CreateAsync(CreateOrganizationDto input)
  7.     {
  8.         await _paymentService.ChargeAsync(
  9.             CurrentUser.Id,
  10.             GetOrganizationPrice()
  11.         );
  12.         var organization = await _organizationManager.CreateAsync(input.Name);
  13.         await _organizationManager.InsertAsync(organization);
  14.         await _emailSender.SendAsync(
  15.             "admin@issuetracking.com",
  16.             "New Organization",
  17.             "A new organization created with name: " + input.Name
  18.         );
  19.         return organization; //!!!
  20.     }
  21.     private double GetOrganizationPrice()
  22.     {
  23.         return 42.0; //或者从其他地方获取
  24.     }
  25. }
复制代码
让我们一步一步地看看 CreateAsync 方法,来讨论代码部分是否应该放在应用程序服务中
讨论:为什么我们不将支付逻辑转移到领域服务中?

您可能想知道为什么支付代码不在 OrganizationManager 中。这是一件很重要的事情,我们不想错过付款
然而,仅仅重要还不足以将代码视为核心业务逻辑。 我们可能还有其他的用例,在这些用例中创建一个新的 Organization 是不需要收费的。比如:
如您所见,支付不是创建有效组织的必要操作。它是特定于用例的应用程序逻辑。
示例: 增删改查 操作
  1. public class IssueAppService
  2. {
  3.     private readonly IssueManager _issueManager;
  4.     public IssueAppService(IssueManager issueManager)
  5.     {
  6.         _issueManager = issueManager;
  7.     }
  8.     public async Task<IssueDto> GetAsync(Guid id)
  9.     {
  10.         return _issueManager.GetAsync(id);
  11.     }
  12.     public async Task CreateAsync(IssueCreationDto input)
  13.     {
  14.         return _issueManager.CreateAsync(input);
  15.     }
  16.     public async Task UpdateAsync(UpdateIssueDto input)
  17.     {
  18.         return _issueManager.UpdateAsync(input);
  19.     }
  20.     public async Task DeleteAsync(Guid id)
  21.     {
  22.         return _issueManager.DeleteAsync(id);
  23.     }
  24. }
复制代码
这个应用程序服务本身不做任何事情,而是将所有工作委托给领域服务。它甚至将 dto 传递给 IssueManager
应用程序服务可以直接使用存储库来查询、创建、更新或删除数据,除非在这些操作期间需要执行一些领域逻辑。在这种情况下,创建 Domain Service 方法,但只针对那些真正需要的方法
如果你对领域驱动设计和构建大型企业系统更感兴趣,推荐以下书籍作为参考书:
完结

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 qidao123.com技术社区-IT企服评测·应用市场 (https://dis.qidao123.com/) Powered by Discuz! X3.4