随着前端从界面展示工具发展为完整业务承载层,系统规模不断扩大,前端逻辑中越来越多出现复杂业务判断、策略选择、流程分支与跨功能协作,传统 UI / API 开发模型逐渐难以应对。许多前端项目在迭代一年后会出现典型问题:模块耦合严重、核心逻辑散落各处、维护成本急速提升、多人协同时经常踩坑。为解决这一矛盾,领域驱动设计(DDD)思想引入前端成为近年来大规模项目的显著趋势。本文结合实践经验,分析 DDD 在前端落地的结构分析、分层设计、领域建模、业务拆分、测试与演进方法,帮助前端在大型系统中构建长期可维护、可演化并减少耦合的业务架构。
一、为什么前端开始需要 DDD
1. 系统业务复杂度急剧提升
当前前端需要承担:
-
价格策略、库存计算等独立业务逻辑
-
工作流、审批流等状态流转
-
低代码规则引擎执行
-
用户权限与灰度策略
如果依然:
-
所有逻辑写在 Vue/React 组件
-
所有判断散落在 Pages 中
-
数据加工拼接在 Service 层完成
系统势必快速变为"无法维护的多头怪兽"。
2. DDD 是解决业务混乱的最佳模式之一
DDD 带来:
-
业务逻辑归纳统一
-
业务语言统一(Ubiquitous Language)
-
模块边界清晰
-
可读、可测、可替换的代码组织结构
前端完全能从中受益。
二、前端 DDD 基本模型
前端应用中,我们采用:
Presentation 层(UI、展示和操作) Application 层(用例流程,协调服务) Domain 层(业务核心逻辑) Infrastructure 层(请求、工具、框架依赖)
它们各承担职责:
1. Presentation(展示)
仅负责:
-
UI 渲染
-
触发动作为事件
-
不包含复杂逻辑
组件越轻,复用性越高。
2. Application(应用层)
负责:
-
用例流程(如客户下单流程)
-
调用领域服务
-
不包含业务规则
例如"订单提交"流程可能包含:
-
校验库存
-
调用折扣策略
-
调用支付
-
记录埋点
但并不执行库存算法逻辑。
3. Domain(领域模型)
负责核心:
-
聚合根
-
领域对象
-
领域服务
-
工厂与仓储接口
示例:
-
订单(Order)
-
购物车(Cart)
-
价格策略(PricingPolicy)
这是系统最不应该受到技术框架影响的部分。
4. Infrastructure(基础设施)
包括:
-
HTTP 请求实现
-
LocalStorage 适配
-
Web Worker
-
日志上报实现
-
外部 SDK 接入
可随意替换,不影响业务层。
三、前端中常见领域建模方法
1. 聚合根(Aggregate Root)
例如购物车:
Cart - Items[] - PricePolicy - TotalPrice - ChangeItem() - CalcPrice()
所有业务行为聚合在领域对象中,而不是散落组件。
2. 领域服务
当行为不属于任何单独实体,可抽出:
-
优惠计算
-
税率算法
-
交付策略
-
额度风控
例如:
ObtainFinalPrice(order: Order) → number
统一封装避免"每个页面 copy 一份"。
3. 仓储(Repository)
负责:
-
读写后端数据
-
缓存封装
-
API 抽象成领域接口
实现与 Mock、灰度、测试全分离。
四、如何拆解复杂业务
1. 一条业务链就是"一个用例"
例如"提交订单":
1. 检查登录 2. 检查库存 3. 价格策略处理 4. 额度校验 5. 订单入库 6. 返回订单编号
流程写在 Application 层:
SubmitOrderUseCase.execute()
而:
-
库存判断
-
价格策略
-
风控校验
均在 Domain 实现。
2. 业务拆分成可组合策略
如价格的形成:
-
商品基础价
-
会员折扣
-
促销活动
-
税率
-
使用券后抵扣价
每项可用:
PricingPolicy[]
组合执行:
policy.reduce((price, p) => p.apply(price), originPrice)
可以:
-
插拔策略
-
灰度策略
-
按渠道定制
-
单元测试隔离验证
业务灵活性显著提升。
五、DDD 对前端测试带来的改变
1. 领域层测试最关键
集中验证:
-
核心业务逻辑
-
不依赖 UI 或请求实现
-
用纯函数或模拟依赖实现
即:
95% 逻辑测试不需要跑浏览器
速度极快、覆盖率高。
2. UI 层只做轻度 E2E
推荐:
-
Cypress
-
Playwright
验证:
-
页面展示正常
-
流程与交互通过
-
用例跑通即可
不再在 UI 层测业务细节。
六、落地后的工程收益
来自真实项目统计:
1. 需求修改速度更快
过去:
-
改一次逻辑 → 改 6 个页面
-
功能关联链长 → 改出 bug 很难定位
现在:
-
改业务逻辑只需改 1 个 domain 类
-
UI 不动
-
代码改动强局部性
维护成本大幅下降。
2. 新人三天即可上手复杂业务
因为:
-
聚合根负责什么
-
应用层负责什么
-
展示层只负责展示
一眼就知道逻辑在哪里。
3. 重构代价更可控
例如:
-
替换缓存介质
-
替换 API SDK
-
修改优惠规则
都不会影响大面积代码。
七、常见落地误区
误区 1:照搬所有 DDD 概念
正确方式:
按需使用,解决业务混乱问题即可
误区 2:领域非常薄、逻辑仍在组件
领域层必须"承得住业务"。
误区 3:基础设施和领域混杂
API 依赖传入 Domain 会变得难以替换,应反转依赖。
八、总结
DDD 在前端不是把代码写复杂,而是:
-
让复杂业务有逻辑容器
-
让团队协作成本下降
-
让逻辑可复用、可替换、可边界化
-
让系统长期运行不腐化
随着前端业务能力不断扩张,DDD 将成为中大型项目前端架构演进的重要支撑。