- 组成限界上下文
- 领域
- 实体(entity) # 标识和延续性, 有id, 持续变化。
- 值对象(value object) # 无id, 只有属性, 最好不可变(可共享)。尽量建模值对象。可包含实体引用或值对象。
- 生命周期
- 聚合(aggregate) # 定义对象所有权和边界
- 简化
- 关联 # 可导航到的关联
- 1对1 # 对象引用
- 1对n # 包含集合
- n对n # 删除关联,关系加约束或转换
- 目的
- 实现
- 聚合根(root) # 聚合根间是最终一致性
- 是个实体,有id
- 外部访问的唯一对象
- 向外传递副本
- 工厂(factory) # 在领域中没有定义, 但程序需要
- 目的
- 并非对象创建对象
- 对象创建存在自有知识
- 创建过程原子性
- 对已有持久化对象重建并修复
- 问题
- 实现
- 不用工厂
- 构造不复杂
- 不涉及其它对象
- 客户希望用策略创建
- 类是具体类型, 无层级
- 聚合根提供方法
- 单独工厂 # 违反了封装原则, 但保持了简单
- 资源库(repository) # 内存假象
- 目的
- 不关联根获取对象引用
- 不暴露细节, 会减少领域专注
- 防止代码扩散
- 减少变更修改
- 维护聚合封装性
- 容易的基础设施被滥用, 产生除聚合根外导航
- 实现
- 封装所有获取对象逻辑
- 基础设施, 全局可访问
- 不同对象不同策略访问、存储 # 领域与基础设施解耦
- 接口是领域模型, 实现像基础设施
- 参数筛选或规约(specification)筛选(筛选器)
- Entity
- 介绍
- entity即状态
- 应用开发即处理entity的表现
- 主从
- 主存储(可变) # 关键是选择主存储
- 只读派生(representation, 不可变)
- 类型
- 东西(可变) # 单据叠加成东西, 东西叠加成东西
- 单据(可变) # 事件叠加成单据
- 事件(event, 不可变)
- 命令(command, 不可变)
- 视图(view model, 不可变)
- 子集(subset, 不可变)
- 视图(aggregation, 不可变)
- 表单(可变) # 是主存储
- 物理介质
- OLTP(mysql) # 点查询
- OLAP(clickHouse) # 范围查询
- queue(kafka) # 顺序读, 低延迟
- 业务服务 # 业务逻辑, 像虚拟的表
- 分组entity主存储(BC, bounded context)
- 目的
- 边界entity # 用于集成,不一定是主存储
- 形式
- 授权、binlog、工作流、视图数据、租户作为其它租户user
- 东西、单据、event
- 介质
- 触发
- queue, ui, api
- 触发由worker托管, 输入是queue或rpc socket
- 粒度
- 关系
- 时间错开
- 外键关系 # BC挂载到BC, 如后台系统与计费系统的定价, 运营人员与服务系统的配置, 流程节点系统对流程的依赖
- 报表关系
- 时效性高
- 一般做复制 # 所以边界entity是数据变更event
- 触发关系 # fire and forget
- 交棒关系
- 下游给上游command/event, 上游触发
- 上游实现降级 # 下游不可用时,安慰语
- 时间同时
- accountable/responsible关系 # 负责人与实现人
- 原则
- accountable尽量小
- 只调度
- 与responsible的边界entity是rpc虚拟表, 请求command, 返回event
- 补偿实现一致 # 如超卖
- responsible提供自己界面 # accountable不控制
- 抢资源关系
- 服务(service) # 无法划分对象的动作, 无状态。按功能分组, 多对象的连接点
- 可在application, domain, infrastructure