2. 医疗业务领域建模与微服务边界划分

在医疗信息化系统中,业务复杂度往往并不来自技术本身,而来自医疗流程的多角色协作、强合规约束和跨科室数据流转。领域驱动设计(DDD)提供了一套从业务语义出发划分系统边界的方法,其核心价值在于:让微服务的边界与医疗业务的真实边界对齐,而不是按技术分层或团队组织来切分。

一、DDD 核心概念在医疗场景中的映射

DDD 的几个关键概念需要先落到医疗语境中理解。领域(Domain)指整个医疗业务范围,例如一家三甲医院的临床与运营业务。子域(Subdomain)是对领域的细分,按业务重要性分为核心域、支撑域和通用域。在医疗场景中,挂号、门诊、住院、检验、影像、药房、收费等就是典型的子域。限界上下文(Bounded Context)是子域的显式边界,在这个边界内,术语、模型和规则保持一致性;跨边界时,同一个词可能含义不同。例如“患者”在挂号上下文中是“就诊人”,在住院上下文中是“在院患者”,在检验上下文中是“标本所属对象”,三者字段和生命周期并不相同。

另一个关键概念是聚合(Aggregate)与聚合根(Aggregate Root)。聚合是一组具有一致性边界的实体和值对象,聚合根是外部访问的唯一入口。以门诊挂号为例,“挂号单”可作为聚合根,包含患者标识、科室、医生、号别、挂号时间、状态等;而“排班号源”更适合作为独立聚合,因为它需要支持高并发扣减,与挂号单的事务边界不同。把号源扣减和挂号单创建强行放进一个聚合,会导致锁竞争和性能问题。

二、医疗子域识别与分类

识别子域时,建议从“业务能力”而非“组织架构”出发。医院的组织架构会调整,但业务能力相对稳定。常见的医疗子域可归纳为以下几类:

  • 核心域:直接体现医院诊疗能力与竞争力的子域,如门诊诊疗、住院诊疗、急诊急救、手术麻醉。
  • 支撑域:支撑核心业务运转但非差异化能力,如挂号、收费、药房、检验、影像、病历归档。
  • 通用域:可采购或复用的通用能力,如用户认证、消息通知、主数据管理、日志审计。

需要强调的是,核心域与支撑域的划分因医院定位而异。对以科研见长的医院,检验和影像可能上升为核心域;对以慢病管理为主的机构,随访和健康管理可能成为核心域。因此子域分类不是一次性工作,而应随业务战略定期复核。

三、限界上下文与微服务拆分原则

限界上下文是微服务拆分的直接依据,但两者并非一一对应。一个限界上下文可能对应一个或多个微服务,一个微服务也可能承载多个紧密相关的限界上下文。拆分时应遵循以下原则:

  1. 业务能力单一:每个服务围绕一个明确的业务能力,如“挂号服务”只负责号源管理与挂号单生命周期,不承担收费计算。
  2. 数据所有权清晰:每个服务独占其数据库,其他服务只能通过接口访问,禁止跨库联表。例如检验服务拥有标本、检验申请、检验结果数据,门诊服务不得直接读取检验库。
  3. 事务边界最小:跨服务采用最终一致性,通过领域事件驱动。如“挂号成功”事件触发“收费待办”和“排队叫号”更新。
  4. 变更频率与团队边界对齐:频繁协同变更的功能应放在同一服务,避免分布式事务开销。
  5. 合规与审计可追溯:涉及患者隐私、处方、收费的服务必须独立记录审计日志,满足等保与医疗数据安全要求。
拆分粒度不是越细越好。一个可参考的经验是:初期按“业务能力”粗粒度拆分,当某服务内部出现明显的变更频率差异或性能瓶颈时,再考虑进一步拆分。

四、医疗子域与限界上下文关系图

下图展示了从医疗领域到子域、再到限界上下文与微服务的映射关系,并标注了跨上下文的主要领域事件流向。图中“挂号—门诊—检验—药房—收费”构成一次典型门诊就诊的主链路,住院、影像作为并行或后续环节接入。

医疗领域 → 子域 → 限界上下文 → 微服务 映射关系 医疗业务领域(Domain) 核心域 门诊诊疗 / 住院诊疗 / 急诊 支撑域 挂号 / 检验 / 影像 / 药房 / 收费 / 病历归档 通用域 认证 / 通知 / 主数据 / 审计 限界上下文(Bounded Context) 门诊上下文 就诊人 / 处方 / 诊断 挂号上下文 号源 / 挂号单 / 退号 检验上下文 申请 / 标本 / 结果 药房上下文 库存 / 调配 / 发药 收费上下文 费用 / 结算 / 发票 住院上下文 床位 / 医嘱 / 护理 影像上下文 申请 / 图像 / 报告 主数据上下文 患者 / 科室 / 人员 认证上下文 账号 / 角色 / 权限 审计上下文 操作日志 / 合规 微服务(Service) 门诊服务 挂号服务 检验服务 药房服务 收费服务 住院服务 影像服务 主数据服务 认证服务 审计服务 领域事件流: 挂号成功 → 门诊接诊 → 检验申请 → 标本采集 → 结果回传 → 处方开具 → 药房调配 → 收费结算

五、从上下文到服务的落地要点

完成上下文划分后,需要为每个上下文定义上下文映射(Context Map),明确上下游关系与集成模式。医疗系统中常见的映射关系包括:

  • 客户—供应商:门诊上下文是检验上下文的客户,检验上下文需按门诊的申请格式提供接口。
  • 共享内核:患者主索引、科室字典等由主数据上下文统一维护,其他上下文只读引用。
  • 防腐层:当需要对接医院原有 HIS 或第三方 LIS 时,在边界处建立防腐层,将外部模型转换为内部模型,避免外部变更污染核心域。

以一次门诊就诊为例,可观察到的跨服务协作过程如下:患者在挂号服务完成挂号,产生“挂号成功”事件;门诊服务订阅该事件后创建就诊记录;医生开具检验申请,检验服务接收申请并生成标本条码;检验完成后回传结果,门诊服务更新就诊记录;医生开具处方,药房服务锁定库存并生成调配任务;收费服务根据处方和检验项目生成待收费明细。整个过程没有跨库联表,各服务通过事件与接口协作,任一环节失败可通过补偿或重试恢复。

边界划分中最常见的错误是“按数据库表拆服务”。例如把患者表、挂号表、收费表分别拆成三个服务,但业务上它们共享同一事务语义,会导致大量分布式事务。正确做法是先识别业务能力与一致性边界,再决定服务粒度。

最后,边界划分不是一劳永逸的。建议在每次重大业务变更或系统重构前,重新审视上下文映射,确认服务边界是否仍然与业务能力对齐。可以用“变更影响分析”作为检验手段:当某个业务规则变化时,需要改动的服务数量越少,说明边界划分越合理。