软件架构之职责边界风格(RB)

软件架构之职责边界风格(RB)

风格名 :职责边界风格(简称 RB 风格

英文名 :Responsibility Boundary Style(RB

一句话:业务按职责切成独立模块,负载与基础设施放在支撑层;写业务代码时不必关心扩容、队列、缓存实现------像写单应用一样简洁。

本文定义一种可独立采用的开发风格与标准。它不绑定某一框架、语言或仓库;任何按同一原则切分业务、外置支撑的系统都可以称为 RB 实现。文末附一份落地案例,仅作对照,不是标准本身。


1. 要解决什么问题

多数系统不是毁在「不会写功能」,而是毁在职责没切干净

常见后果 根因
改一处、炸一片 业务模块互相引用实现,耦合成一张网
业务代码越写越脏 队列、缓存、线程池、分库键散落在用例代码里
扩容必须改业务 负载能力绑在业务方法上,而不是绑在支撑层
拆服务等于重写 边界只在口头上,代码里仍是进程内直调实现

良好的软件工程,首先应定好职责边界。边界一旦含糊,模块化、微服务、高并发都只是把混乱换了一种部署形态。

RB 风格的立场是:

  • 业务模块化,避免代码耦合、牵一发动全身。
  • 支撑能力外置,负载能力不侵入、不绑定业务代码。
  • 开发体验单应用化:封装支撑细节后,业务开发者只写用例。

2. 风格定义

职责边界风格是一种以「职责」为第一刀、以「支撑外置」为第二刀的模块化风格:

text 复制代码
                    ┌─────────────────────────────────┐
                    │          业务层(可替换、可拆分)   │
                    │  按域划分的业务模块                 │
                    │  只表达:谁在什么条件下做什么         │
                    └────────────────┬────────────────┘
                                     │ 只认契约(接口 / 事件)
                    ┌────────────────▼────────────────┐
                    │          支撑层(可升级、可扩容)   │
                    │  通信 · 缓存 · 安全 · 部署装配      │
                    └────────────────┬────────────────┘
                                     │
                    ┌────────────────▼────────────────┐
                    │          数据层(由库自身承担负载)  │
                    │  索引 · 事务 · 隔离 · 容量规划      │
                    └─────────────────────────────────┘

三层含义:

  1. 业务与业务之间:强边界。只依赖对方的契约,不依赖对方的实现与表结构。
  2. 业务与支撑之间:单向依赖。业务使用支撑提供的稳定 API;支撑不得反向依赖某个业务域。
  3. 负载与业务之间:解绑。吞吐、排队、重试、水平扩展是支撑层与数据层的职责,不是业务方法里的「技巧」。

这与「先上微服务再谈治理」相反:先把边界写进代码与仓库结构,部署形态可以后变。


3. 三条主原则

3.1 业务分模块:边界写进结构,而不是写进口头

模块是职责单元,不是包名装饰。

要求 含义
一个模块一件事 各业务域自成一体,不互相吞并实现
契约与实现分离 对外只暴露契约;实现与持久化留在模块内部
禁止实现级耦合 禁止业务模块依赖他域的实现包或持久化模型
变更半径可控 重构某一模块内部,只要契约不变,其他模块零改动

判定:一个模块的内部重构,只要契约不变,其他模块应零改动。若做不到,边界就还不够强。

3.2 支撑外置:负载能力不绑定业务代码

业务开发者不必关心本模块明天是 1 个实例还是 20 个实例。负载能力应作为支撑层提供:

支撑能力 放哪 业务侧只看见
模块间通信 消息中间件(同步请求-应答 + 异步事件) 调用契约方法 / 发布领域事件
水平扩展 装配单元 + 竞争消费 + 入口分流 配置与部署,不改用例代码
重试 / 死信 统一的消息基线 业务只保证幂等
会话、验证码等短时数据 统一的短时存储门面 按命名空间读写,不手写中间件方言
认证与安全 支撑层过滤器与会话存储 业务只取当前用户,不实现令牌解析

消息中间件在本风格中的位置 :它不是「异步的可选项」,而是模块间通讯的支撑介质。中间件天生具备排队、缓冲、多消费者竞争、按域拆通道等负载能力;把通讯交给这一层之后,业务代码不必自己做线程池堆积、手工远程调用他域、或在用例里写扩容分支。

封装支撑细节的目标只有一句:

写业务就像写单应用一样简洁。

3.3 支撑能力不得侵入业务代码

「用了缓存 / 消息 / 数据库」不等于「业务里要出现这些实现细节」。

能力 正确职责 侵入业务时的样子(禁止)
缓存 加速与临时存储(短 TTL 凭证、会话快照) 把缓存当第二数据库;业务里散落客户端、自创存储分区、用缓存表达领域状态
消息 跨模块通讯与削峰 业务里手写中间件客户端、手配通道绑定、事务未提交就发消息
数据库 持久化与数据层负载 用缓存硬扛本该由索引 / SQL / 库容量解决的查询;把分库键、路由策略写进用例

数据库负载的理想结果 :查询慢、写入争用、容量上限,应尽量由数据库自身解决------索引、执行计划、隔离级别、只读副本、分库分表(若必须)落在数据层及其配置,而不是渗进业务分支。业务只描述「存什么、按什么业务键查」。

缓存可以加速热点读、保存临时凭证,但不能成为业务正确性的来源,也不能替代本该建的索引与合理的表设计。


4. 标准条款

以下条款把风格落成可检查的标准。违反任一条,即视为偏离 RB 风格。条款描述的是职责与约束,不规定必须使用哪一种框架或命名。

4.1 职责边界

  1. 跨模块只依赖契约:接口、传输对象、枚举、可订阅的事件定义。
  2. 契约层不得依赖任何业务实现,不得引用他域(或本域实现层)的持久化模型。
  3. 仅本模块使用的配置维护、渠道插件、管理端专属操作,留在模块内部,不升格为跨模块契约。
  4. 模块边界由自动化检查守护(架构测试、依赖扫描等),而不是只靠人工记忆。

4.2 支撑外置

  1. 传输与中间件实现只存在于支撑层。业务模块禁止自实现跨模块远程客户端。
  2. 同步协作:注入契约并调用方法,体验等同本地调用;底层走进程内直调或远程请求-应答,由配置切换,业务代码不变。
  3. 异步协作:在数据提交成功之后发布事件,由他域订阅处理;禁止用进程内广播冒充跨模块协作。
  4. 有数据库事务时,发消息等副作用必须在提交之后执行;由支撑层提供「提交后再做」的能力。

4.3 负载与数据

  1. 扩容优先改装配与拓扑(多实例、按域拆部署、入口分流),而不是改业务算法「以适配高并发」。
  2. 缓存只用于加速与临时存储;业务状态以数据库为准。
  3. 数据库访问保持业务语义(按业务键查询与关联);负载与存储优化下沉到库与持久层配置。
  4. 业务代码不堆砌厂商中间件方言(连接工厂、通道名、缓存分区名等由支撑层约定或自动生成)。

4.4 开发体验

  1. 默认形态可以是模块化单体(多业务模块进同一进程),以便交付;契约已按远程协作书写,拆进程时业务代码不变。
  2. 新增跨模块能力时先问「要不要立即返回」:要 → 同步契约调用;不要且需广播 → 事件。不要在业务里临时开一条「方便的直连」。

5. 与相邻思想的关系

RB 风格不否定既有方法,而是给出一套组合与优先级

思想 关系
模块化单体 常见的默认部署形态:边界先于进程。单进程不等于无边界。
微服务 演进结果,不是起点。契约不变,只换装配与入口分流。
整洁架构 / 六边形 同样强调业务不依赖基础设施细节;RB 进一步把「负载」明确划给支撑层与数据库。
DDD 限界上下文 模块 ≈ 上下文。RB 要求把上下文做成仓库结构与自动化检查都能守护的硬边界。
消息驱动 消息是支撑层通讯,不是把所有用例都做成最终一致。需要立即返回的编排仍走同步契约。

刻意不做的事:一上来按流量拆服务、在业务里用缓存「模拟」数据库、让每个模块自己封装一套远程调用。那些都会把职责边界重新搅浑。


6. 一分钟自检

做设计或 Review 时只问五句:

  1. 这件事属于哪个业务模块? 不能回答,说明职责还没切。
  2. 他域是否只依赖契约? 若引用了别人的持久化模型或实现类,边界已破。
  3. 这段代码是在表达业务,还是在表达负载? 后者应回到支撑层或数据层。
  4. 拿掉缓存实现 / 换消息中间件 / 把该域拆成独立进程,用例方法是否仍可读? 若大量改业务,说明支撑已侵入。
  5. 这个读压力是否本该由数据库解决? 先索引与查询,再谈缓存。

全部能干净回答,即符合职责边界风格。


7. 命名说明

全称 职责边界风格 ,简称 RB 风格(Responsibility Boundary)。选用这一名称,而不是「模块化单体」或「微服务」,是因为:

  • 职责边界是第一刀:先切清谁负责什么,再谈进程数与技术栈。
  • 风格表示可复用的开发约定,不是某一种部署拓扑的别名。
  • 模块化是落实边界的手段;单体或微服务只是支撑层上的装配选择。风格的稳定性来自边界与外置,而不是来自「现在有几个进程」。

附录 · 案例:TG-boot

以下仅说明 TG-boot 如何实现 RB,便于对照本仓库代码。条款本身不依赖这些类名与模块名;换一套实现,只要满足上文标准,仍是 RB。

RB 概念 TG-boot 中的落点
业务模块 spring-boot-starter-components / business 下各域 *-api + *-biz
支撑层(通信、缓存、安全、消息基线) spring-boot-starter-common
装配与负载拓扑 spring-boot-starter-runner;可按域再拆 runner
边界守护 spring-boot-starter-architecture-tests
同步契约 Api**Service + ModuleApi 代理(LOCAL 或 MQ Request-Reply)
异步契约 *-api/subscribe/XxxConsumerMqPublisher.publishAfterCommit
短时缓存 TgEphemeralCache(单区域 + namespace::key
持久化约定 BaseEntity + 业务主键 xxxCode;负载问题优先在库侧解决
相关推荐
智慧物业老杨3 小时前
人机协同的物业服务重构:技术落地路径与系统化思考
java·大数据·人工智能·重构·系统架构
威嵌神州3 小时前
VxWorks6.9 BSP 适配:飞腾 D2000/FT2000/4 平台、驱动开发
驱动开发·嵌入式硬件·fpga开发·系统架构
weixin_424183614 小时前
Little 定律与 Gateway 链路并发分析
系统架构
m0_587383006 小时前
上海24小时自助健身房系统软件开发实战指南:从架构到部署
人工智能·小程序·数据挖掘·系统架构·需求分析
doiito(Do It Together)7 小时前
【Agent Harness】Gliding Horse 最新进化:从“能学习”到“可验证的自主进化”
人工智能·rust·系统架构·开源
智慧物业老杨12 小时前
物业数字化落地思考:真正的转型,是底层数据秩序的重构
java·大数据·人工智能·微服务·系统架构
Alice-YUE18 小时前
工业级 AI Agent 架构:5 层、2 范式、4 原则,一次讲透
面试·系统架构·大模型·ai agent·智能体
江屿风1 天前
【Linux系统】【Linux进程终止等待详解与程序替换机制初体验】流食般投喂
linux·运维·笔记·系统架构·centos·unix
LONGZETECH1 天前
深入拆解无人机组装四大技术难关:焊接、接线、调参、转向校验
大数据·人工智能·系统架构·无人机