【DDD】抽奖活动实战

669 阅读4分钟

「这是我参与2022首次更文挑战的第11天,活动详情查看:2022首次更文挑战

一、前言

针对业务流程,可以将系统分成两个业务领域:

  1. 面向 C 端(客户端)的抽奖系统
  2. 面向 M 端(管理端)的抽奖管理平台领域

DDD 建模步骤:

工程落地、概要设计、详细设计、编码开发。

  1. 划分限界上下文(划分子域)
  2. 子域的集成关系
  3. 实体建模

1. 划分限界上下文(划分子域)

抽奖活动子域:作为一个支撑子域。

原因有三:

  1. 这个子域功能:在抽奖的过程封装一些数据,同时配合进行抽奖的各种校验和限制。
  2. 核心的抽奖业务和行为不在这个子域里。
  3. 如果这个子域都作为核心域,那么这个大系统里的子域基本都可为核心域。

奖品库存子域:作为一个支撑子域。

奖品库存跟抽奖获的配置有关,但是两个概念,得独立区分开来。 作用:配合抽奖行为过程中的库存校验相关的业务。

抽奖风控子域:作为一个支撑子域。

作用:使用大数据技术去实时和离线分析用户行为,利用机器学习的算法来识别出一些刷单、薅羊毛的行为。

营销子域:作为一个支撑子域。

抽奖系统外部的系统。 作用:发放券。

订单中心子域::作为一个支撑子域。

抽奖系统外部的系统。 作用:去下订单(实物商品)。

会员中心子域:作为一个支撑子域。

抽奖系统外部的系统。 作用:增加虚拟金币。


2. 子域的集成关系

上下问映射关系:定义不同子域/子系统之间的上下游关系、集成关系。

术语简介:

  • Uupstream):上游,服务提供者。

  • Ddownsteam):下游,服务调用者。

  • 合作关系(Partnership):两个上下文强耦合在一起。

  • 共享内核(Shared Kernel):两个上下文中间一起商量定义一个通用的领域模型。

  • 客户方-供应方开发(Customer-Supplier Development):上下文之间互相有商有量的进行通用语言的设计

    比如接口提供方设计接口和模型:会问调用方,调用方也会提自己的需求给提供方。

  • 遵奉者(Conformist):设计通用语言的时候,按照服务提供方来实现。

  • 防腐层(Anticorruption Layer):对其他的服务进行接口调用的时候,要把接口返回给你的东西做一下转换,转换为你内部的实体,避免人家接口改变,你这里就变,这是防腐的一个层。

  • 开放主机服务(Open Host Service) 和 发布语言(Published Language):这一般是大公司内部,有那种中心之间的调用交互,暴露开放接口,定义一种协议/语言,一般都是 RESTful API,或者是第三方公司开放给你的接口。

  • 大泥球(Big Ball of Mud):搞的一塌糊涂

  • 独立路线(SeparateWay):没关系

结合上面术词,可画出抽奖活动的集成关系图:

ddd-抽奖活动.png


3. 实体建模

根据业务需求,来定义实体类、聚合类等。

  1. 实体类:抽奖行为
/**
 * 抽奖行为
 */
@Component
@Scope("prototype")
public class DrawLottery {
    /**
     * 一次抽奖行为的标识符
     */
    private Long id;
    /**
     * 进行抽奖的用户id
     */
    private Long userId;
    /**
     * 抽奖活动id
     */
    private Long lotteryDrawActivityId;
    
    /**
     * 执行本次抽奖
     * @return 抽奖结果
     */
    public String execute() {
        
        // ... ... 
    }
}
  1. 抽奖算法
/**
 * 抽奖算法
 */
@Component
@Scope("prototype")
public class DrawLotteryAlgorithm {
    /**
     * 执行抽奖算法
     * @return 中奖
     */
    public WinPrize execute() {
        // ... ...
    }
}

精髓:实体之间交互

  • 实体与实体之间调用,而不是直接调用对应 serviceapi

  • 接口是比较底层的。

  • 屏蔽细节。



二、项目框架

项目目录结构如下:

├─ lottery-draw-activity         # 抽奖活动子域
├─ lottery-draw-activity-api     # 抽奖活动子域接口:定义一些 `VO` 和接口
├─ lottery-draw-core             # 抽奖活动核心
├─ lottery-draw-preize-stock     # 抽奖活动奖品库存子域
├─ lottery-draw-preize-stock-api # 抽奖活动奖品库存子域接口:定义一些 `VO` 和接口
├─ lottery-draw-risk-control     # 抽奖活动风险子域
└─ lottery-draw-risk-control-api # 抽奖活动风险子域接口:定义一些 `VO` 和接口