08-领域模型
领域模型——正向从业务建模型,逆向从模型展开成流程
领域模型有两条方向:正向是从业务语言/现实问题分析出对象、属性、关系、规则与状态(把业务世界压缩成一个模型);逆向是把已经建好的模型展开成开发流程——转成具体的步骤序列,每一步做什么、产出什么都有明确约定。正向回答「业务世界里有什么」,逆向回答「有了模型之后按什么顺序、一步步把它变成程序」。
一、正向:从业务语言到领域模型
1.1 一个例子:图片管理器
要做一个图片管理器,不能直接开始写界面。先问:这个软件操作的对象是什么?
1 | Project 项目(一组图片的集合) |
这就是领域模型的第一步:识别领域对象。
再往下,对象有属性、有关系、有状态:
1 | Project |
界面、仓库、库本质上都是领域对象的可视化/持久化操作接口。 界面上的每个按钮、列表、对话框,背后都对应一个领域对象或对它的操作。
1.2 正向怎么建:从现实问题分析抽象
建领域模型的完整路径:
1 | 现实问题(业务世界)/ 业务语言 |
① 找对象(名词)
业务描述里的名词往往是领域对象:
1 | 「用户可以新建项目,把图片按文件夹整理,搜索时按元数据过滤」 |
从这里挑出软件要操作的、有状态的对象:Project / Folder / ImageFile / SearchQuery。
② 找属性
每个对象回答「它是什么」:
1 | ImageFile:路径、格式、宽度、高度、大小、修改时间 |
③ 找关系
对象之间回答「谁和谁怎么连接」:
1 | Project ─包含→ Folder ─包含→ ImageFile |
④ 找规则和状态
回答「对象怎么变化、哪些变化是允许的」:
1 | ImageFile:Closed → Opened → Modified → Saving → Saved |
四步做完,领域模型就成型了——它描述的是业务世界的结构,与界面、数据库、语言都无关。 这一步本身就是「正向建模」在领域上的应用成果:从具体业务里抽出共同结构与规则,形成一个模型(见 03-建模与逆向 正向建模)。
二、逆向:从领域模型展开成流程与步骤
模型只是空间结构(谁包含谁、谁依赖谁),工程却是时间顺序(先做什么、后做什么)。领域模型的逆向不是「重新拆模型」,而是把模型展开成一条可执行的流程——一个包含每个步骤做什么的序列。
1 | 领域模型(空间:对象 / 属性 / 关系 / 规则 / 状态) |
2.1 逆向的核心:先按依赖排序,再逐步展开
把模型转成步骤,依据的是对象之间的依赖:
- 没有依赖的对象先做(基础数据先成型);
- 被依赖的结尾后做(依赖它们的逻辑最后做)。
以图片管理器为例,领域模型对象存在依赖:
1 | ImageMetadata → ImageFile → Folder → Project → SearchQuery → 状态模型 |
于是得到步骤序列(每个步骤都产出可验证的东西):
| 步骤 | 做什么 | 产出(可检查) |
|---|---|---|
| 1 | 定义基础数据对象 | ImageMetadata(尺寸/格式/时间) |
| 2 | 定义核心数据对象 | ImageFile(元数据 + 内容路径) |
| 3 | 定义容器对象 | Folder(图片列表)/ Project(文件夹 + 元数据) |
| 4 | 定义查询对象 | SearchQuery(条件/过滤规则) |
| 5 | 定义状态模型 | Project / ImageFile 的状态转换(见下) |
| 6 | 定义对象操作 | 打开/保存/删除/搜索(对模型中的对象的操作) |
| 7 | 连上界面 | 界面上的动作 = 领域对象的操作(右键删除 = project.delete(image)) |
每一步都「做什么」定了,产出也可检查,这就是从模型展开出的第一条流程。
2.2 状态模型:领域模型中规则与状态的落地
模型里的规则(状态)单独展开成 状态模型(State Model)——它就是前一步中「状态转换表」的展示:
1 | ImageFile 的状态模型: |
界面上的按钮可用/不可用,就是状态模型的投影:Closed 时「保存」按钮 disabled;Opened|Saving 时才可用。
2.3 从模型逆向出完整流程(GUI 图片查看器案例)
从领域模型出发逆向出完整工程流程——每一步都清楚「做什么」:
1 | 领域模型(Image/ImageCollection/ImageMetadata/ViewState) |
每个步骤「做的是什么」都明确:⑥ 是在搭工程,⑦ 是从底层到界面一层层把领域模型落到代码。整条链是领域模型的逆向展开:模型 → 流程(上面的步骤序列)→ 每个步骤可执行、可验证。
2.4 更复杂的逆向:CLI 工具从模型到实现的完整流程
一个 CLI 数据扫描工具(如逆向工具/调试器),其领域模型(FILE/PROCESS/MODULE 等)可逆向成 CLI 工程的完整步骤链(见 06-设计/07-CLI程序的设计顺序、07-工程控制/02):
1 | 领域模型文档(Process/Module/Symbol/Breakpoint...) |
这里每一个步骤都是把「领域模型」往前推一步:模型 → 程序类型 → 需求点 → 功能 → 模块 → 接口 → 数据结构 → 代码。每一步的输入、输出、做什么都有明确约定(步骤 | 输入 | 输出 | 说明),所以整套流程可以照做。
同一条逆向规律也适用于其他领域: 角色设计从一句「画一个可爱的少女」出发,也要经过语义 → 外观 → 比例 → 参数 → 草图 → 三视图 → 最终成品的流程——其中「比例」不是普通参数而是关系,被单独抽成一层;素描的核心是「结构/形状/比例/约束 → 画 → 比较 → 修正 → 完成」(模型在每次比较/修正中被验证并更新)。这就是「抽象描述也需要经过领域建模,再转换成一系列设计流程」。
2.5 逆向执行时,模型会被修正
逆向流程不是一次跑完:执行中发现问题(缺对象、状态不对、规则不足)时回到模型修改它,再继续展开。这是一次完整的闭环:
1 | 领域模型(正向的产物) |
模型不是最终答案,而是当前阶段对业务世界的压缩描述——反向执行时不断「比较与修正」,每次修正都会让模型更接近真实(这正是 03-建模与逆向 的双向循环:模型 → 应用 → 验证 → 修正 → 再模型)。
三、领域模型 vs 数据结构
两条线容易混淆,区别在于抽象程度:
1 | 领域模型:业务世界的压缩描述(对象、属性、关系、规则、状态) |
1 | 调试器: |
领域模型回答「业务世界里有什么」,数据结构回答「这些在程序里怎么存」。 领域模型先于数据结构——先有对象,才谈得上怎么表示。(对应 04 数据结构线:数据结构来自领域对象分析→领域模型链)
四、领域模型 vs 领域对象分析
这两条线也相关,但不同:
1 | 领域模型:把整个业务领域建成一个模型(对象+属性+关系+规则+状态) |
领域对象分析是建领域模型的第一步——先会找对象,才能建完整模型。找对象这件事,一般软件和游戏/建模的做法不同,所以领域对象分析又分成两条线(见 06/07 两篇文章)。
五、反向的收益:为什么值得单独建模型
直接写代码 vs 先建模型:
1 | 直接写代码: |
典型收益:底层变化大,模型不变。
1 | 调试器换底层实现(win32 → 其他平台) |
六、正向与逆向在这个模型里的位置
1 | 正向:现实需求 → 对象 → 属性 → 关系 → 规则+状态 → 领域模型 |
工程里逆向顺序不唯一,但一般是从模型逐步走进时间(先做基础对象→容器→状态→UI→流程→集成)。上面的例子(GUI 图片管理器、CLI 工具、角色设计)就是同一套模型逆向展开成不同流程的案例。
七、和其他线的关系
1 | 领域模型 ←→ 数据结构(04) |
收束
1 | 正向:从业务语言 → 对象(名词)→ 属性 → 关系 → 规则+状态 → 领域模型 |
先有对业务世界的模型,再把模型展开成一步步的流程去实现。 正向建模型,逆向成流程——这正是一个完整闭环。
