ワンクリックで
rabbitadvisors
以虚拟公司 RabbitTech 的知识付费产品 RabbitAdvisors 为例,完整演示从领域建模到微服务落地的全流程 DDD 实践。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
以虚拟公司 RabbitTech 的知识付费产品 RabbitAdvisors 为例,完整演示从领域建模到微服务落地的全流程 DDD 实践。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
以聚合根为边界,包含多个相关Entity和ValueObject的集合。保证数据一致性和事务边界。
在DDD中具有唯一身份标识和生命周期的对象,通过身份而非属性值相等判断。
封装复杂对象和聚合的创建过程,将创建职责从领域对象中剥离,保证聚合创建时的不变量满足。
没有身份标识,通过属性值判断相等的对象。不可变,通常代表领域中的度量或描述。
命令查询责任分离,将数据的写入操作和读取操作分别用不同的模型处理,优化各自的性能。
将DDD战略设计应用于微服务架构,限界上下文指导服务拆分,领域事件实现服务间通信。
| name | RabbitAdvisors 知识付费案例研究 |
| description | 以虚拟公司 RabbitTech 的知识付费产品 RabbitAdvisors 为例,完整演示从领域建模到微服务落地的全流程 DDD 实践。 |
公司:RabbitTech
产品:RabbitAdvisors(知识付费 / 付费咨询平台)
核心业务流程:
核心问题:作为 CTO,如何对 RabbitAdvisors 进行架构设计,如何给团队分工?
本案例贯穿战略设计 → 战术设计 → 架构落地全流程,展示 DDD 方法论在真实 B 端业务中的应用。
从现金流出发,识别两条关键现金往来:
[ColumnQuote 专栏报价] [ContributorContract 撰写合同]
│ (编辑定价) │ (签约时约定)
▼ ▼
[Order 订单] ──金额相等──▶ [Payment 支付] [Commission 佣金]
│ │ (账期内 Σ Payment × percentage)
▼ ▼
[Subscription 订阅] [CommissionPayment 分成支付]
│
└─触发─▶ [积分增加等下游事件]
通过凭证链可以提炼出关键的领域对象:
实体 / 聚合根:
▸ Reader 读者 ▸ Author 作者 ▸ Editor 编辑
▸ Column 专栏 ▸ ColumnQuote 报价
▸ Order 订单 ▸ Payment 支付
▸ Subscription 订阅
▸ ContributorContract 合同 ▸ Commission 佣金
▸ CommissionPayment 分成支付
领域事件:
▸ ColumnQuoted 专栏已报价 ▸ OrderCreated 订单已创建
▸ PaymentCompleted 支付已完成 ▸ SubscriptionCreated 订阅已创建
▸ CommissionCalculated 佣金已计算 ▸ CommissionPaid 分成已支付
值对象:
▸ Money 金额(amount + currency)
▸ Period 账期(开始、结束)
▸ CommissionRate 分成比例
关键设计决策:读者、编辑、作者虽然都可以登录,但在系统中从事的动作、拥有的能力差异巨大,因此将它们视为三个独立的领域模型,而非一个"用户"基类。"用户"的共性仅体现在登录、个人信息等少数场景。
┌─────────────────────────────────────────────────────────────┐
│ RabbitAdvisors 领域 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 核心域: │
│ ├── 订单域 (Order) ← 决定交易质量 │
│ └── 订阅域 (Subscription) ← 核心交付能力 │
│ │
│ 支撑域: │
│ ├── 专栏域 (Column) │
│ ├── 专栏报价域 (ColumnQuote) │
│ ├── 金融域 (Payment) │
│ ├── 签约域 (Contract) │
│ ├── 佣金域 (Commission) │
│ ├── 评论域 (Comment) │
│ └── 公告域 (Announcement) │
│ │
│ 通用域: │
│ ├── 读者域 (Reader) │
│ ├── 编辑域 (Editor) │
│ ├── 作者域 (Author) │
│ ├── 消息通知域 (Notification) │
│ └── 登录鉴权域 (Auth) │
│ │
└─────────────────────────────────────────────────────────────┘
类型划分依据:
限界上下文划分的关键技巧:一个限界上下文必须支持一个完整的业务流程。
限界上下文 1:专栏订阅上下文
包含子域:订单域、订阅域、读者域
业务流程:读者选择专栏 → 下单 → 支付 → 订阅 → 阅读
限界上下文 2:专栏信息上下文
包含子域:专栏域、专栏报价域、评论域、公告域、编辑域
业务流程:编辑创建专栏 → 定价 → 发布 → 读者浏览
限界上下文 3:签约分佣上下文
包含子域:签约域、佣金域、作者域
业务流程:作者签约 → 按账期计算佣金 → 生成分成支付单
限界上下文 4:金融上下文
包含子域:支付域、分成支付域
业务流程:处理所有现金往来(对接支付网关)
限界上下文 5:用户信息上下文
包含子域:读者域、编辑域、作者域的公共部分、认证域
业务流程:登录、注册、个人信息维护
⇒ 5 个限界上下文 = 5 个微服务:
smart-classroom-subscription(专栏订阅系统)smart-classroom-column(专栏信息系统)smart-classroom-contract(签约分佣系统)smart-classroom-finance(金融系统)smart-classroom-user(用户信息系统)团队分工:5 个小组,每组负责一个限界上下文,形成 康威定律 的正向实践。
用例图:
Actor "读者" --> (浏览专栏)
(查看专栏详情)
(订阅专栏)
(查看我的订阅)
(阅读专栏内容)
状态机 (Subscription):
┌─────┐ create ┌────────┐ cancel ┌──────────┐
│ 无 │ ───────▶ │ ACTIVE │ ───────▶ │ CANCELLED │
└─────┘ └────┬───┘ └──────────┘
│ expire
▼
┌──────────┐
│ EXPIRED │
└──────────┘
活动图(订阅):
读者 → 点击订阅 → [订单系统] 创建订单 → [金融系统] 支付
→ [订阅系统] 创建订阅 → 发送"订阅成功"事件 → 成长域增加积分
时序图(订阅):
Reader → Subscription/Facade → OrderApp → PaymentClient → SubscriptionDomain
ER 图(数据库建模):
t_subscription (id, reader_id, column_id, start_time, end_time, status, ...)
t_order (id, reader_id, column_id, amount, status, ...)
t_payment (id, order_id, amount, paid_at, status, ...)
// 聚合根 Subscription
public class Subscription {
private final SubscriptionId id; // 唯一标识
private final ReaderId readerId;
private final ColumnId columnId;
private final Instant startTime;
private final Instant endTime;
private SubscriptionStatus status;
// 工厂方法:从支付完成事件创建
public static Subscription fromPayment(Payment payment, Column column) {
if (!payment.isCompleted()) {
throw new DomainException("支付未完成不能创建订阅");
}
return new Subscription(
SubscriptionId.generate(),
payment.getPayerId(),
column.getId(),
payment.getCompletedAt(),
payment.getCompletedAt().plus(column.getDuration())
);
}
// 业务行为
public void cancel() {
if (status != SubscriptionStatus.ACTIVE) {
throw new DomainException("只有活跃订阅可以取消");
}
this.status = SubscriptionStatus.CANCELLED;
}
public boolean isActiveFor(Instant time) {
return status == SubscriptionStatus.ACTIVE
&& !time.isBefore(startTime)
&& !time.isAfter(endTime);
}
}
"订阅"这个动作涉及 订单创建 + 支付 + 订阅创建 等多个聚合,无法放到单一实体中,识别为领域服务:
@Component
public class SubscriptionDomainService {
private final OrderFactory orderFactory;
private final PaymentClient paymentClient; // 调用金融域(防腐层接口)
private final ColumnFacadeClient columnClient;
private final SubscriptionRepository subscriptionRepo;
public Subscription subscribe(ReaderId readerId, ColumnId columnId) {
// 1. 校验专栏可订阅、读者未重复订阅
Column column = columnClient.getActive(columnId);
if (subscriptionRepo.existsActive(readerId, columnId)) {
throw new DomainException("已订阅过该专栏");
}
// 2. 创建订单
Order order = orderFactory.create(readerId, column);
// 3. 发起支付
Payment payment = paymentClient.pay(order);
// 4. 创建订阅(工厂方法)
Subscription subscription = Subscription.fromPayment(payment, column);
subscriptionRepo.save(subscription);
return subscription;
}
}
@Service
public class SubscribeAppService {
@Autowired private SubscriptionDomainService subscriptionDomainService;
@Autowired private DomainEventPublisher eventPublisher;
@Transactional
public SubscriptionInfo subscribe(SubscribeCommand cmd) {
Subscription subscription = subscriptionDomainService.subscribe(
new ReaderId(cmd.getReaderId()),
new ColumnId(cmd.getColumnId())
);
eventPublisher.publish(new SubscriptionCreatedEvent(
subscription.getId(), subscription.getReaderId(), subscription.getColumnId()
));
return Model2InfoConverter.toInfo(subscription);
}
}
[专栏订阅上下文] [成长体系上下文](假想扩展)
发布 SubscriptionCreated ──MQ──▶ 订阅 SubscriptionCreated
└──▶ 为读者增加积分
[签约分佣上下文]
订阅 PaymentCompleted ──MQ──▶ 累计到作者的佣金统计
每个微服务内部按 DDD 分层:
smart-classroom-subscription/
├── subscription-main (启动入口)
├── subscription-facade (对外 RPC 接口声明)
├── subscription-facade-impl (接口实现)
├── subscription-controller (HTTP 入口,可选)
├── subscription-application (用例编排、事务、事件)
├── subscription-domain (核心:聚合、领域服务、仓储接口)
│ ├── subscription/ ← 订阅聚合包
│ ├── order/ ← 订单聚合包
│ └── shared/ ← 共享值对象
├── subscription-repository (仓储实现、Mapper、DO)
├── subscription-infrastructure (防腐层实现、MQ 客户端)
├── subscription-utility (工具类)
└── subscription-testsuite (测试)
后端:
▸ Spring Boot (应用框架)
▸ MyBatis (ORM)
▸ MySQL (存储)
▸ Dubbo (RPC)
▸ Nacos (注册中心 / 配置中心)
▸ RocketMQ (消息队列 / 领域事件)
▸ Maven (构建)
前端:
▸ React / TypeScript / React Router / Antd / Less / Vite
业务侧: 技术侧:
▸ 统一语言 → 代码、文档、沟通一致
▸ 子域识别 → 资源合理分配(核心域多投)
▸ 业务脊梁 → 稳定不变的业务骨架
▼
架构侧:
▸ 限界上下文 → 微服务拆分依据
▸ 聚合 → 事务边界
▸ 分层架构 → 团队协作规范
smart-classroom-misc 中以简化演示,真实项目也可根据团队规模权衡| 概念 | 本案例体现 |
|---|---|
| 四色建模法 | 第一阶段从现金流推导凭证链 |
| 子域划分 / 域类型 | 第三阶段识别核心/支撑/通用域 |
| 限界上下文 | 第四阶段划分 5 个微服务 |
| 聚合 | Subscription / Order 聚合 |
| 领域服务 | SubscriptionDomainService |
| 应用服务 | SubscribeAppService |
| 领域事件 | SubscriptionCreated 跨上下文解耦 |
| 分层架构 | 完整的 COLA 分层落地 |
https://github.com/eyebluecn/smart-classroom-mischttps://github.com/eyebluecn/smart-classroom-subscriptionhttps://github.com/eyebluecn/smart-classroom-front核心:通过 RabbitAdvisors 这一完整案例,展示了 DDD 从发现业务脊梁 → 划分域 → 设计聚合 → 编写代码的全链路实践。
精髓:
DDD 不是银弹,深刻理解业务才是架构师的核心能力。