分享一下组内小伙伴雷羽、张聪在优惠券系统上落地领域建模的总结

一、引入领域建模的原因模型转换:

  1. 将数据库模型转换为实体模型,最终操作实体模型持久化到数据库保存(一个id即可表示有且仅有一张优惠券)
  2. 行为内聚:使用DDD领域实体模型,使优惠券相关行为内聚到实体(查询、领取、折扣计算、自动选券、使用)
  3. 面向扩展:优惠券种类繁多,却又大同小异,针对不同类型优惠券实现基础函数(满减券、津贴、折扣券、抵扣券)
  4. 向上弥合数据源差异,隐藏实现细节,比如根据不同的用户发放个性化的优惠券(不同的人面额门槛适用范围不一样),通过统一的领域模型隐藏掉该种券在使用等方面的差异;
  5. 模型灵活转换实现复用,比如在劝buy会员等预支场景,我们通过预领取优惠券(实际用户并没有该优惠券)将Coupon模型转化为UserCoupon模型,来实现优惠计算的复用;

二、实体设计

  • 优惠券:解决用户领取问题
    图片
  • 基础优惠券领域实体Coupon,提供优惠券所有基础能力(包含查询优惠券信息出参转换、领取、预领取、对内提供的优惠金额计算能力)
    图片
  • 聚焦不同类型券重写优惠金额计算(折扣券、抵扣券、津贴、满减券),在诸如商详、劝buy会员等用户未获得该券的场景下,通过Coupon.receiveInAdvance将模型转换为UserCoupon,由UserCoupon统一承担复杂的使用规则验证,仅支撑核心的金额计算部分功能;
    图片
  • 用户优惠券:对外提供优惠计算、消费、归还等能力
    图片
  • 基础用户优惠券UserCoupon,提供用户优惠券所有基础能力(包含查询用户优惠券信息出参转换、计算优惠金额、自动选券、消费、退还);
    图片
  • 用户满减券、用户折扣券、用户抵扣券、用户津贴针对不同类型券实现优惠金额计算、选取可用sku;
    图片
  • 隐藏千人一券、千人千券的不同构造过程,隐藏真实与预领取优惠券的能力差异,实现模型的高度复用;
    图片
  • 兑换券领取兑换券(引用可兑换的优惠券Coupon实体)
    图片
  • 缓存与序列化,因为Voucher引入Coupon实体,Coupon实体本身已经缓存,所以Voucher的缓存交由SerializableVoucher,仅持久化couponId;
    图片
  • 用户兑换券消费能力:兑换商品、兑换优惠券使用(引用Voucher实体)兑换后使用同UserCoupon  三、核心代码领取条件:通过不同维度如(渠道、用户身份、领取时间、领取方式、领取数量)等校验
    图片
  • 使用条件:通过不同维度如(门槛、用户身份、使用对象spu、使用时间、使用平台/方式、订单限制)等校验
    图片
  • 预领券:VIP劝Buy、宠粉券计算优惠等,提前给满足客观条件的用户预领抵扣
    图片
  • 自动选券:通过优惠券优惠金额、过期时间、门槛、优惠券类型等条件帮用户自动选出最为合适的券
    图片

四、主线流程

  • 领券
    图片
  • 用券
    图片
  • 退还
    图片

image.png


答案在风中
139 声望47 粉丝

程序员,先后供职于盛大、阿里巴巴、一条,目前在字节🐂🐴