美文网首页
14.构造块领域模式介绍

14.构造块领域模式介绍

作者: 鸿雁长飞光不度 | 来源:发表于2022-08-19 20:55 被阅读0次

如何创建领域模型并和分析模型绑定,DDD使用了包含若干构造块的模式的语言,来实现领域模型,这是一种采用面向对象的方式,是第5章里面提到领域模型实现方式的一种,其他的方式可以按实际情况采用。

image.png

上图展示了领域模型中的许多概念和它们的关联关系,下面是详细介绍。

1. 领域建模相关

下面概念表示了问题域的逻辑,表述了模型对象的关联关系。

  1. 实体:表示领域中的概念,由身份而不是特性来定义,是业务中承担行为的对象,比如产品、订单。

[图片上传中...(image.png-a82323-1660748013800-0)]

  • 具有唯一标识
    • 提前生成:唯一标识工具。ice
    • 持久化机制生成:数据库自增id。
  • 要点
    • 构造方法完成唯一标识设定,并且以后不能被修改
    • 属性赋值验证
      • 属性:单个属性调用set方法的时候直接验证,通过才能赋值。
      • 组合验证:给实体增加validate方法,或者专门建立validate类验证。
    • 跟踪变化:领域事件和事件存储、发布订阅模式。订单状态的变化。

这里提到用一个实体定义一个基类,提供默认的构造方法、相等比较方法(比较id)、hashcode方法,其他的实体集成并重载部分方法。

  1. 值对象:用于描述领域实体的特性,具有不变性,没有唯一身份标识、

案例:『数字』,『日期』,『邮寄地址』,这是用于度量或者描述领域中某件东西的概念。比如年龄(出生了多少年)、名字(称呼)。

image.png
  • 特性

    • 不变性:构造函数完成值对象创建,一旦创建后属性不可改变。

    • 概念整体:值对象描述整体的概念

      Class ThingOfWorth {
          private string name;
          private int money;
          private string currency;
      }
      //改进后
      Class ThingOfWorth {
          private string name;
          private MoneyValue worth;//资产
      }
      Class MoneyValue {
           private int money;
           private CURRENCY currency;
      }
      
      
    • 可替换性:实体对象对值对象的替换是简单的。

      • 简单类型 entity.total = 4; 改成entity.total = 3;
      • 复杂类型
      entity.value = value1; 
      Value v2 = new Value(2,3);
      entity.value = v2;
      
    • 相等性:自定义equals方法对比。

    • 无副作用:值对象对外提供的方法不改改变值,相当于问值对象问题,这样的表达方式更具有表达性。

    Class ExamResult {
        private math;
        private english;
        
        public function getAmount()
        {
            return this->math + this->english
        }
    }
    
    • 非常简单的类型不需要封装为值对象,布尔,数值类型。

    • 值对象引用实体

      //businessPriority 值对象
      //product 实体对象
      float priority = businessPriority.priorityOf(product);
      改进后
      float priority = businessPriority.priority(
      product.businessPriorityTotals());
      
      • 值对象尽量只理解自身的属性和状态。
      • 第一段代码并不知道使用了Product哪些部分,表达不清晰。
      • 不能看出是否会对product的属性进行修改。
    • 值对象实现(构造方法)

      • 有参数和无参数的(根据配置给属性赋值的)
      • 根据另一个值对象复制(可能没有必要)
    • 持久化值对象:(不是存入数据库的就必须是实体),有时值对象需要以实体的身份持久化。


值对象和实体的选择(描述,是,是,不是的回答用值对象)

是领域的一个东西,还是只是描述或者度量东西?
如果是描述,能否满足值对象的特征?
将该概念建模成实体是不是只是持久化机制考虑?
如果建模成实体是不是因为拥有唯一标识,需要关注实体的个体性,并需要在声明周期跟踪变化。?

  1. 领域服务

表示一个无状态的操作,用于实现某个特定的领域任务,某些操作不适合放在聚合和值对象上就用领域服务,比如计价、身份认证。

过度使用领域服务导致领域贫血模型:表现现象为所有的业务逻辑都在领域服务中,而不是实体和值对象中

  • 适用场景
    1. 执行一个显著的业务操作过程。
    2. 对领域对象进行转换。
    3. 以多个领域对象作为输入进行计算,结果产生值对象。

4.模块

image.png

通过模块(包或者命名空间实现)将领域模型的不同领域对象分组,实现高内聚低耦合,让不同部分可以被单独理解。

2.生命周期模式

1.聚合

image.png

业务中实体和值对象组合用于描述领域模型中复杂的关联关系,比如上图,我们很难同时保持上述复杂关联关系的并发性和一致性,比如我们不能仅仅因为一个较早的订单状态发生变化,就阻止用户更新账户的地址,因为这两个行为不相关,没有必要保持并发和一致性,我们可以把不同实体按照相关性和关联性划分成聚合,每次都通过聚合根修改数据,多个聚合之间用聚合根id引用,而不能直接引用聚合的数据。

image.png

比如两个人同时要修改同一个产品的颜色和尺寸,产品是聚合根,这里要保证并发和一致性,不能丢失数据,可以提前对产品id加锁的方式解决,也可以在更新数据的时候通过数据库的乐观锁形式比如update xx where id = 1 and color = before_color这样的断言,更新行数为0提示更新失败。

聚合的划分不能仅仅通过入口,通过入口划分后要考虑不变条件

image.png

这里再次划分成为电子钱包地址簿聚合,这样修改地址和信用卡可以同时进行,修改信用卡比如通过电子钱包这个聚合根实现。

在举一个例子:申请单和申请明细条目,比如创建了一个申请单,在申请单状态是等待审核之前或者被驳回时是可以修改申请内容的,正在审核中或者审核完成是不能修改的,这里修改申请明细就需要通过申请单这个聚合根来修改。

聚合必须总是处于一致性状态,相当于原子单元、聚合根会充当入口点,聚合外部的对象不能保留对聚合内部对象的引用

2.工厂

对象或者值对象创建比较复杂时,应该使用工厂,工厂确保对象创建之前满足所有的不变性条件,不复杂的时候使用简单的构造器方法。

3.存储库

聚合内部是原子操作保持一致性,需要将聚合变更的数据持久化,聚合和存储库用ORM框架可以关联做到数据存储和读取。

image.png

3.显露模式

1.领域事件

当聚合或者实体发生变化的时候,可以将事件发布,其它方可以根据自己需要监听,比如购物车发生加购或者减购的时候要为用户推荐不同的菜,加减商品就可以作为领域事件发布,推荐系统去监听。领域事件也可以作为聚合之间通信的手段。

2.事件溯源

比如对于订单状态来说,订单状态已创建、已付款、已发货、配送中,可以将每次订单变化的事件都记录下来,有利于做分析溯源,比如订单为什么减少了?

相关文章

  • 14.构造块领域模式介绍

    如何创建领域模型并和分析模型绑定,DDD使用了包含若干构造块的模式的语言,来实现领域模型,这是一种采用面向对象的方...

  • 战术模式简介

    战术模式包含若干构造块模式,以便能够构建有效的领域模型。 战术模式严重依赖于领域模型和通用语言,通过技术模式将领域...

  • java中的构造代码块

    1、介绍 java中用"{}"括起来的称为代码块,代码块可分为以下四种:静态代码块 、构造代码块、构造方法块、普通...

  • Java程序执行顺序

    执行顺序大致分类: 静态属性,静态方法声明,静态块。 动态属性,普通方法声明,构造块。 构造方法。 详细介绍: 类...

  • JavaScript中创建对象的几种方式

    在《JavaScript高级程序设计》中,介绍了创建对象的7种方式,分别是:工厂模式、构造函数模式、原型模式、构造...

  • JavaScript创建对象之原型模式

    一、原型基础 在之前的文章:《JavaScript创建对象之单例、工厂、构造函数模式》中详细介绍了构造函数模式创建...

  • 组合使用构造函数模式和原型模式创建对象

    介绍 创建自定义类型的最常见方式,就是组合使用构造函数模式和原型模式。构造函数模式用于定义实例属性,而原型模式用于...

  • js继承

    关于js继承,阮一峰的文章介绍的非常详细; 继承两种模式:1.构造函数模式2.非构造函数模式 http://www...

  • 前端面试题总结【37】:javascript对象的几种创建方式

    工厂模式 构造函数模式 原型模式 混合构造函数和原型模式 动态原型模式 寄生构造函数模式 稳妥构造函数模式 推荐:...

  • Java代码块的执行顺序

    执行顺序首先执行静态代码块接着执行构造代码块最后指向构造方法 静态代码块 >>> 构造代码块 >>>> 构造方法 ...

网友评论

      本文标题:14.构造块领域模式介绍

      本文链接:https://www.haomeiwen.com/subject/faysgrtx.html