前言:内容来源于哲玄前端 的《大前端全栈实践》课程
什么是领域模型
领域模型就是对你要解决的问题领域里的"东西"和"关系"的一个整理和描述
换句话说,就是把你要做的事情里重要的角色、物品、规则,用一个清晰的"模型"表现出来
领域模型包含的内容
1. 实体(Entities)
定义:实体是有唯一身份标识的业务对象,即使它的属性发生变化,它依然是同一个实体。
例子:
- 用户(User) :每个用户都有唯一的用户ID,比如手机号或账号。
- 订单(Order) :每个订单有唯一的订单号。
- 配送员(DeliveryPerson) :每个配送员有唯一的员工编号。
这些实体可以随着时间属性变化(比如用户地址变了,订单状态变了),但它们的身份不变。
2. 值对象(Value Objects)
定义:值对象没有唯一标识,完全由它的属性值定义。两个值对象的属性相同,它们就是相同的
例子:
- 地址(Address) :包含街道、城市、邮编等信息。两个地址属性完全一样,就认为是同一个地址
- 货币(Money) :包含金额和币种,比如"100元人民币"
值对象通常是不可变的,修改时是创建一个新的值对象
3. 聚合(Aggregates)
定义:聚合是以某个实体作为聚合根,将所有与该实体相关的对象(包括实体和值对象)组织在一起,形成一个一致性的边界。聚合根负责统一管理聚合内部的数据和业务规则,确保聚合内部的一致性和完整性。
例如:用户聚合就是以"用户"这个实体作为聚合根,把所有和用户相关的对象(实体或值对象)组织在一起,形成一个聚合。这个聚合内部的数据和业务规则由用户聚合根统一管理,保证聚合内部的一致性
例子:
-
订单聚合(Order Aggregate) :
- 聚合根是订单(Order)。
- 订单包含多个菜单项(MenuItem)和配送信息(DeliveryInfo,可能是值对象)。
- 外部系统只能通过订单这个聚合根来访问和修改订单相关的数据,保证数据一致性。
4. 领域服务(Domain Services)
定义:领域服务是那些不属于某个实体或值对象,但封装重要业务逻辑的操作。
例子:
- 订单处理服务(OrderProcessingService) :负责处理订单的创建、支付、状态变更等业务逻辑。
- 配送分配服务(DeliveryAssignmentService) :负责给订单分配合适的配送员。
这些服务通常是无状态的,专注于业务操作。
5. 领域事件(Domain Events)
定义:领域事件表示领域中发生的重要事情,通常用于通知系统其他部分发生了某个业务事件
例子:
- 订单已创建(OrderCreatedEvent) :当用户成功下单后触发
- 订单已配送(OrderDeliveredEvent) :配送员完成配送后触发
6. 约束和规则
定义:业务规则和不变式,保证业务逻辑的正确性。
例子:
- 一个订单只能有一个当前状态(比如"待接单"、"配送中"、"已完成")。
- 用户只能给自己所在区域内的餐厅下单。
- 配送员一次只能配送一个订单。
这些规则通常写在实体或领域服务中,确保系统不会进入非法状态
项目的设计理念
- 数据驱动站点的生成 :不管是前端还是后端,在做后台管理系统这类项目时,本质都是为了数据服务,而该项目的作用就是,基于数据源来生成整个的站点 ,通过一套基于
json-schema
规范把源数据转化成对应的json配置 - DSL+解释器 :当拿到数据源 对应的json配置 ,我们通过编写数据源解释器 生成相应的内容,比如说配置库表解释器,可以生成对应的表,配置api解释器可以生成对应的api,前端部分也是一样,我们通过数据源驱动页面生成的生成,核心在于一切都是为了数据而服务,关于具体的实现只是配置不同的解释器
这样设计的好处
- 模板复用 :由于后台管理系统中存在大量重复的业务逻辑,可以通过沉淀通用的 DSL 模型 (基类),通过继承基类生成对应定制化的子类(基类 -> 子类),每个子类都是一个项目的具体配置
- 源数据生成站点:一个站点只需要一个源数据配置,拿到板块数据结构后通过对应的解释器,生成对应的内容

这样设计的缺点
调试难度大
- 间接性强
通过解释器间接生成代码或结构,出错时难以定位问题根源,调试链条长。 - 错误传播风险
配置错误或 DSL 设计缺陷可能导致生成的代码或数据库结构异常,影响系统稳定性。
成本高昂
- 学习曲线陡峭
团队成员需要理解 DSL 语法、继承体系和解释器机制,培训成本较高 - 依赖核心设计者
DSL 和解释器设计者成为关键人物,知识传递和文档不足时,团队风险增加
其他方案对比
低代码/无代码平台
-
核心思想:通过可视化界面和配置驱动,快速搭建业务应用,减少手写代码。
-
实现方式:拖拽组件、配置数据模型、业务流程,平台自动生成代码和运行环境。
-
优点:
- 学习成本低,只需要会拖拉拽即可
- 内置大量通用后台组件和模板,复用性强
-
缺点:
- 覆盖面小,只能快速搭建前端内容
- 后端仍会重复开发CRUD的工作