ABP 框架实战系列(二)- 领域层介绍篇

EF Core 全称是Entity Framework Core,可使用 EF Core 开发面向 .NET Core 的应用,EF Core 同时支持在 Visual StudioVisual Studio for Mac 或 Visual Studio Code 等环境下开发。

若有朋友对EF Core不是很熟悉,可以通过篇文章了解一下EF Core 快速入门教程,在此就不重复介绍了,该公众号推荐关注,知识点满满。

EF Core 之所以在ABP模板中特别抽出来,并不是因为这里的EF Core 有何特别之处,而是这里的EF Core 对领域对象负责。

ABP框架架构介绍中有提到 ABP 不仅仅是一个架构,它还是提供了一个最佳实践的基于领域驱动设计(DDD)的体系结构模型。

如下图所示,ABP在应用层和持久化层中间,有一个领域层.

ABP 层级

领域层概述

领域驱动设计(DDD):DDD原本定义为一种软件开发的解决方案,始于统一语言,经由绑定上下文,最终得到一个以业务模型对象为中心的分层架构。遵循DDD的原则,常见的开发步骤:了解需求、把需求转化为规范、实际编码以及测试。DDD的目的是应付业务领域的核心复杂行。但是,使用DDD需要建立在对业务领域的精准把握之上。正确得使用DDD会是软件的开发实施变得非常简单

领域层的结构大致如下

领域层的内部

  • 领域模型

    • 模块
    • 值对象

      DDD领域模型包含实体和值对象。值对象完全通过它的特性来定义。值对象的特性在实例创建之后就不会改变了。如果要改同时变,值对象会变成另一个值对象的实例

    • 实体Entity Class

      实体是从实体类派生的
      所有对象都有特性,但不是所有的对象都能完全通过它们的特性集合来标识。这些对象就是实体。换句话说,如果对象需要一个ID特性在整个生命周期的上下文里唯一跟踪它,这个对象就有一个身份标识,且被看成实体。值对象只是聚合在一起的数据,实体通常由数据和行为构成。行为是区别对待领域逻辑和应用程序逻辑的关键。领域逻辑在领域层中,用例的实现则在应用程序里

      
      public class Person : Entity
      {
          public virtual string Name { get; set; }
      
          public virtual DateTime CreationTime { get; set; }
      
          public Person()
          {
              CreationTime = DateTime.Now;
          }
      }
      

      人员类定义为一个实体。它有两个属性。此外,实体类定义id属性。它是实体的主键。因此,所有实体的主键名称相同,它是id。

      id(主键)的类型可以更改。这是int(Int32)默认。如果要将另一类型定义为id,则应显式声明如下所示:

      
        public class Person : Entity<long>
        {
            public virtual string Name { get; set; }
      
            public virtual DateTime CreationTime { get; set; }
      
            public Person()
            {
                CreationTime = DateTime.Now;
            }
        }
      
    • 实体持久化

      领域模型必须持久化,但是,它不关心持久化。领域模型的实现里没有涉及加载和保存的操作。但是持久化操作对于一个应用程序时必不可少的部分。这时,由仓储负责这些工作。仓储通常都是在领域模型之外使用,比如应用程序层、领域服务。但是,仓储的契约在领域层,它的实现在基础设施层理。

  • 聚合

当开发者根据需求里的用例为绑定上下文构建领域模型,你会发现一些单个实体总是互相引用。逻辑上相关的对象被单独对待而不是组合起来且被当作一个整体对待很容易导致数据泥团代码。这时可以通过聚合对模型里的实体进行分组和隔离。通常的做法是先把领域模型分解成聚合,然后在聚合里标识出领域实体。

    • 优点

      • 业务逻辑变得更加简单
      • 防止紧耦合模型
    • 关系

      聚合的根类对调用方隐藏了相关的类,且要求调用方在进行任何交互时引用它们。换句话说,一个实体只允许引用同一个聚合的实体或者另一个实体的根。当一个聚合需要引用多个另一个聚合中非跟类的实体,该聚合应该引用另一个聚合的根实体。

    • 创建

      聚合根对象是组成这个聚合的对象群的根。聚合根在整个领域模型都可见,且可以直接引用。聚合里的实体任有它们的身份标识和生命周期,但是它们不能从聚合之前直接引用。聚合根也有相应的责任:

      • 聚合根保证聚合内的对象总是按照应用程序iyewu规则有效状态
      • 聚合根负责持久化所有被封装的对象
      • 聚合根负责级联更新以及删除聚合里的实体
      • 查询操作只能获取聚合根。
    • 领域服务

      领域服务类的方法实现的领域逻辑不属于特定聚合,且可能跨越多个实体。为了实现业务操作,领域服务协调聚合和仓储的活动。在某些时候,领域服务可能使用基础设施服务,比如发送电子邮件或者短信

      • 服务即契约
      • 跨聚合行为
      • 仓储
    • 领域事件

      领域事件用于在某些领域事件发生时触发一个事件。这样可以避免在同一个地方放置所有处理代码。

      • 开发人员可以在不触碰产生事件的代码的情况下动态定义一组处理器
      • 可以在多个地方触发相同的事件

    ## 博主GitHub地址
    https://github.com/yuyue5945

    关注公众号留下您的困惑或见解

    公众号


    于跃
    14 声望1 粉丝